aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMic Bowman2011-02-03 12:43:46 -0800
committerMic Bowman2011-02-03 12:43:46 -0800
commitcf24069227f9a32272c873d4423e2e11f5da25a8 (patch)
treea88f39073401978953ef803d2920f60e70f32143
parentAddresses mantis #5360: CreatorData was being written as long as it wasn't nu... (diff)
downloadopensim-SC_OLD-cf24069227f9a32272c873d4423e2e11f5da25a8.zip
opensim-SC_OLD-cf24069227f9a32272c873d4423e2e11f5da25a8.tar.gz
opensim-SC_OLD-cf24069227f9a32272c873d4423e2e11f5da25a8.tar.bz2
opensim-SC_OLD-cf24069227f9a32272c873d4423e2e11f5da25a8.tar.xz
Change UpdateAgent (for changes in agent position) to be sent
once to each simulator rather than once to each region. This should help with some of the delays caused by multiple outstanding requests to a single service point.
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs43
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs55
3 files changed, 81 insertions, 31 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index c5972dd..56720b7 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -225,17 +225,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
225 if (destination == null) 225 if (destination == null)
226 return false; 226 return false;
227 227
228 // We limit the number of messages sent for a position change to just one per
229 // simulator so when we receive the update we need to hand it to each of the
230 // scenes; scenes each check to see if the is a scene presence for the avatar
231 // note that we really don't need the GridRegion for this call
228 foreach (Scene s in m_sceneList) 232 foreach (Scene s in m_sceneList)
229 { 233 {
230 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 234 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
231 { 235 s.IncomingChildAgentDataUpdate(cAgentData);
232 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
233 s.IncomingChildAgentDataUpdate(cAgentData);
234 return true;
235 }
236 } 236 }
237 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); 237 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
238 return false; 238 return true;
239 } 239 }
240 240
241 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) 241 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index f8ff308..837e655 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -193,7 +193,8 @@ namespace OpenSim.Region.Framework.Scenes
193 } 193 }
194 } 194 }
195 195
196 public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, ulong regionHandle); 196 public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
197
197 198
198 /// <summary> 199 /// <summary>
199 /// This informs all neighboring regions about the settings of it's child agent. 200 /// This informs all neighboring regions about the settings of it's child agent.
@@ -202,31 +203,17 @@ namespace OpenSim.Region.Framework.Scenes
202 /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. 203 /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
203 /// 204 ///
204 /// </summary> 205 /// </summary>
205 private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, ulong regionHandle) 206 private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest)
206 { 207 {
207 //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); 208 //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
208 try 209 try
209 { 210 {
210 //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); 211 m_scene.SimulationService.UpdateAgent(dest, cAgentData);
211 uint x = 0, y = 0;
212 Utils.LongToUInts(regionHandle, out x, out y);
213 GridRegion destination = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
214 m_scene.SimulationService.UpdateAgent(destination, cAgentData);
215 } 212 }
216 catch 213 catch
217 { 214 {
218 // Ignore; we did our best 215 // Ignore; we did our best
219 } 216 }
220
221 //if (regionAccepted)
222 //{
223 // //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent");
224 //}
225 //else
226 //{
227 // //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent");
228 //}
229
230 } 217 }
231 218
232 private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) 219 private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
@@ -240,14 +227,28 @@ namespace OpenSim.Region.Framework.Scenes
240 // This assumes that we know what our neighbors are. 227 // This assumes that we know what our neighbors are.
241 try 228 try
242 { 229 {
230 uint x = 0, y = 0;
231 List<string> simulatorList = new List<string>();
243 foreach (ulong regionHandle in presence.KnownChildRegionHandles) 232 foreach (ulong regionHandle in presence.KnownChildRegionHandles)
244 { 233 {
245 if (regionHandle != m_regionInfo.RegionHandle) 234 if (regionHandle != m_regionInfo.RegionHandle)
246 { 235 {
247 SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; 236 // we only want to send one update to each simulator; the simulator will
248 d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, regionHandle, 237 // hand it off to the regions where a child agent exists, this does assume
249 SendChildAgentDataUpdateCompleted, 238 // that the region position is cached or performance will degrade
250 d); 239 Utils.LongToUInts(regionHandle, out x, out y);
240 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
241 if (! simulatorList.Contains(dest.ServerURI))
242 {
243 // we havent seen this simulator before, add it to the list
244 // and send it an update
245 simulatorList.Add(dest.ServerURI);
246
247 SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
248 d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
249 SendChildAgentDataUpdateCompleted,
250 d);
251 }
251 } 252 }
252 } 253 }
253 } 254 }
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index c5313fc..cc6bffb 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -48,6 +48,9 @@ namespace OpenSim.Services.Connectors.Simulation
48 { 48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 // we use this dictionary to track the pending updateagent requests, maps URI --> position update
52 private Dictionary<string,AgentPosition> m_updateAgentQueue = new Dictionary<string,AgentPosition>();
53
51 //private GridRegion m_Region; 54 //private GridRegion m_Region;
52 55
53 public SimulationServiceConnector() 56 public SimulationServiceConnector()
@@ -133,10 +136,56 @@ namespace OpenSim.Services.Connectors.Simulation
133 /// </summary> 136 /// </summary>
134 public bool UpdateAgent(GridRegion destination, AgentPosition data) 137 public bool UpdateAgent(GridRegion destination, AgentPosition data)
135 { 138 {
136 // we need a better throttle for these 139 // The basic idea of this code is that the first thread that needs to
137 // return false; 140 // send an update for a specific avatar becomes the worker for any subsequent
141 // requests until there are no more outstanding requests. Further, only send the most
142 // recent update; this *should* never be needed but some requests get
143 // slowed down and once that happens the problem with service end point
144 // limits kicks in and nothing proceeds
145 string uri = destination.ServerURI + AgentPath() + data.AgentID + "/";
146 lock (m_updateAgentQueue)
147 {
148 if (m_updateAgentQueue.ContainsKey(uri))
149 {
150 // Another thread is already handling
151 // updates for this simulator, just update
152 // the position and return, overwrites are
153 // not a problem since we only care about the
154 // last update anyway
155 m_updateAgentQueue[uri] = data;
156 return true;
157 }
158
159 // Otherwise update the reference and start processing
160 m_updateAgentQueue[uri] = data;
161 }
138 162
139 return UpdateAgent(destination, (IAgentData)data); 163 AgentPosition pos = null;
164 while (true)
165 {
166 lock (m_updateAgentQueue)
167 {
168 // save the position
169 AgentPosition lastpos = pos;
170
171 pos = m_updateAgentQueue[uri];
172
173 // this is true if no one put a new
174 // update in the map since the last
175 // one we processed, if thats the
176 // case then we are done
177 if (pos == lastpos)
178 {
179 m_updateAgentQueue.Remove(uri);
180 return true;
181 }
182 }
183
184 UpdateAgent(destination,(IAgentData)pos);
185 }
186
187 // unreachable
188 return true;
140 } 189 }
141 190
142 /// <summary> 191 /// <summary>