This commit is a major change on the TP process. Several things were wrong and/or broken. (a) ExpectAvatarCrossing is redundant (and bad) because the client triggers the same method on the receiving region after it receives TeleportFinish. (b) At least two of the *Async methods in SceneCommunicationService weren't asynchronous at all; I made them be asynchronous. Crossing fingers...

0.6.2-post-fixes
diva 2008-12-22 07:06:01 +00:00
parent 69fe246fcc
commit 339fd602db
2 changed files with 98 additions and 72 deletions

View File

@ -196,20 +196,20 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
agent.InventoryFolder = UUID.Zero; agent.InventoryFolder = UUID.Zero;
agent.startpos = position; agent.startpos = position;
agent.child = true; agent.child = true;
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
Thread.Sleep(2000); // brand new agent, let's create a new caps seed
// brand new agent
agent.CapsPath = Util.GetRandomCapsPath(); agent.CapsPath = Util.GetRandomCapsPath();
}
if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent))
{ {
avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
return; return;
} }
Thread.Sleep(3000); if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
{
// TODO Should construct this behind a method // TODO Should construct this behind a method
capsPath = capsPath =
"http://" + reg.ExternalHostName + ":" + reg.HttpPort "http://" + reg.ExternalHostName + ":" + reg.HttpPort
@ -220,6 +220,11 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
OSD Item = EventQueueHelper.EnableSimulator(realHandle, endPoint); OSD Item = EventQueueHelper.EnableSimulator(realHandle, endPoint);
eq.Enqueue(Item, avatar.UUID); eq.Enqueue(Item, avatar.UUID);
// ES makes the client send a UseCircuitCode message to the destination,
// which triggers a bunch of things there.
// So let's wait
Thread.Sleep(2000);
Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath);
eq.Enqueue(Item, avatar.UUID); eq.Enqueue(Item, avatar.UUID);
} }
@ -237,8 +242,8 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
+ "/CAPS/" + agent.CapsPath + "0000/"; + "/CAPS/" + agent.CapsPath + "0000/";
} }
m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
position, false); // position, false);
//if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
// position, false)) // position, false))
@ -251,7 +256,9 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
// return; // return;
//} //}
Thread.Sleep(7000); avatar.MakeChildAgent();
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
m_log.DebugFormat( m_log.DebugFormat(
"[CAPS]: Sending new CAPS seed url {0} to client {1}", agent.CapsPath, avatar.UUID); "[CAPS]: Sending new CAPS seed url {0} to client {1}", agent.CapsPath, avatar.UUID);
@ -276,9 +283,6 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
/// Hypergrid mod stop /// Hypergrid mod stop
/// ///
avatar.MakeChildAgent();
Thread.Sleep(3000);
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
if (KiPrimitive != null) if (KiPrimitive != null)
{ {
KiPrimitive(avatar.LocalId); KiPrimitive(avatar.LocalId);
@ -293,7 +297,11 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
/// ///
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
{ {
Thread.Sleep(5000); // FinishTeleport makes the client send CompleteMovementIntoRegion (at the destination), which
// trigers a whole shebang of things there. So let's wait plenty before we disconnect.
// The user is already there anyway.
Thread.Sleep(8000);
avatar.Close();
CloseConnection(avatar.UUID); CloseConnection(avatar.UUID);
} }
// if (teleport success) // seems to be always success here // if (teleport success) // seems to be always success here

View File

@ -531,7 +531,7 @@ namespace OpenSim.Region.Environment.Scenes
//bool val = m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region)); //bool val = m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region));
} }
public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ulong regionHandle);
/// <summary> /// <summary>
/// This informs all neighboring regions about the settings of it's child agent. /// This informs all neighboring regions about the settings of it's child agent.
@ -540,29 +540,27 @@ namespace OpenSim.Region.Environment.Scenes
/// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
/// ///
/// </summary> /// </summary>
private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence) private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ulong regionHandle)
{ {
//m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + presence.Scene.RegionInfo.RegionName); //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + presence.Scene.RegionInfo.RegionName);
//bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
try try
{ {
foreach (ulong regionHandle in presence.KnownChildRegionHandles) m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
}
catch
{ {
bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); // Ignore; we did our best
}
if (regionAccepted) //if (regionAccepted)
{ //{
//m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent"); // //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent");
} //}
else //else
{ //{
//m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent"); // //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent");
} //}
}
}
catch (InvalidOperationException)
{
// We're ignoring a collection was modified error because this data gets old and outdated fast.
}
} }
@ -575,23 +573,33 @@ namespace OpenSim.Region.Environment.Scenes
public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence) public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence)
{ {
// This assumes that we know what our neighbors are. // This assumes that we know what our neighbors are.
try
{
foreach (ulong regionHandle in presence.KnownChildRegionHandles)
{
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
d.BeginInvoke(cAgentData,presence, d.BeginInvoke(cAgentData, regionHandle,
SendChildAgentDataUpdateCompleted, SendChildAgentDataUpdateCompleted,
d); d);
} }
}
catch (InvalidOperationException)
{
// We're ignoring a collection was modified error because this data gets old and outdated fast.
}
public delegate void SendCloseChildAgentDelegate(UUID agentID, List<ulong> regionlst); }
public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle);
/// <summary> /// <summary>
/// This Closes child agents on neighboring regions /// This Closes child agents on neighboring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
protected void SendCloseChildAgentAsync(UUID agentID, List<ulong> regionlst) protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle)
{ {
foreach (ulong regionHandle in regionlst)
{
m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle);
//bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); //bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
// let's do our best, but there's not much we can do if the neighbour doesn't accept. // let's do our best, but there's not much we can do if the neighbour doesn't accept.
@ -608,7 +616,6 @@ namespace OpenSim.Region.Environment.Scenes
//} //}
}
//// We remove the list of known regions from the agent's known region list through an event //// We remove the list of known regions from the agent's known region list through an event
//// to scene, because, if an agent logged of, it's likely that there will be no scene presence //// to scene, because, if an agent logged of, it's likely that there will be no scene presence
//// by the time we get to this part of the method. //// by the time we get to this part of the method.
@ -627,12 +634,14 @@ namespace OpenSim.Region.Environment.Scenes
public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst) public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst)
{ {
// This assumes that we know what our neighbors are. foreach (ulong handle in regionslst)
{
SendCloseChildAgentDelegate d = SendCloseChildAgentAsync; SendCloseChildAgentDelegate d = SendCloseChildAgentAsync;
d.BeginInvoke(agentID, regionslst, d.BeginInvoke(agentID, handle,
SendCloseChildAgentCompleted, SendCloseChildAgentCompleted,
d); d);
} }
}
/// <summary> /// <summary>
/// Helper function to request neighbors from grid-comms /// Helper function to request neighbors from grid-comms
@ -681,6 +690,8 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
Vector3 lookAt, uint teleportFlags) Vector3 lookAt, uint teleportFlags)
{ {
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE] RequestTeleportToLocation {0} ", position.ToString());
if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
return; return;
@ -784,18 +795,18 @@ namespace OpenSim.Region.Environment.Scenes
agent.child = true; agent.child = true;
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
Thread.Sleep(2000); // brand new agent, let's create a new caps seed
// brand new agent
agent.CapsPath = Util.GetRandomCapsPath(); agent.CapsPath = Util.GetRandomCapsPath();
}
if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent))
{ {
avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
return; return;
} }
Thread.Sleep(3000); if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
{
// TODO Should construct this behind a method // TODO Should construct this behind a method
capsPath = capsPath =
"http://" + reg.ExternalHostName + ":" + reg.HttpPort "http://" + reg.ExternalHostName + ":" + reg.HttpPort
@ -806,6 +817,11 @@ namespace OpenSim.Region.Environment.Scenes
OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, endPoint); OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, endPoint);
eq.Enqueue(Item, avatar.UUID); eq.Enqueue(Item, avatar.UUID);
// ES makes the client send a UseCircuitCode message to the destination,
// which triggers a bunch of things there.
// So let's wait
Thread.Sleep(2000);
Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath);
eq.Enqueue(Item, avatar.UUID); eq.Enqueue(Item, avatar.UUID);
} }
@ -824,8 +840,9 @@ namespace OpenSim.Region.Environment.Scenes
// Expect avatar crossing is a heavy-duty function at the destination. // Expect avatar crossing is a heavy-duty function at the destination.
// That is where MakeRoot is called, which fetches appearance and inventory. // That is where MakeRoot is called, which fetches appearance and inventory.
// Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates.
m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
position, false); // position, false);
//{ //{
// avatar.ControllingClient.SendTeleportFailed("Problem with destination."); // avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
// // We should close that agent we just created over at destination... // // We should close that agent we just created over at destination...
@ -835,7 +852,9 @@ namespace OpenSim.Region.Environment.Scenes
// return; // return;
//} //}
Thread.Sleep(7000); avatar.MakeChildAgent();
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
m_log.DebugFormat( m_log.DebugFormat(
"[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
@ -853,9 +872,6 @@ namespace OpenSim.Region.Environment.Scenes
teleportFlags, capsPath); teleportFlags, capsPath);
} }
avatar.MakeChildAgent();
Thread.Sleep(3000);
avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
if (KiPrimitive != null) if (KiPrimitive != null)
{ {
KiPrimitive(avatar.LocalId); KiPrimitive(avatar.LocalId);
@ -866,7 +882,11 @@ namespace OpenSim.Region.Environment.Scenes
if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
Thread.Sleep(5000); // FinishTeleport makes the client send CompleteMovementIntoRegion (at the destination), which
// trigers a whole shebang of things there. So let's wait plenty before we disconnect.
// The user is already there anyway.
Thread.Sleep(8000);
avatar.Close();
CloseConnection(avatar.UUID); CloseConnection(avatar.UUID);
} }
@ -879,8 +899,6 @@ namespace OpenSim.Region.Environment.Scenes
m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID);
} }
// Close this ScenePresence too
//avatar.Close();
} }
else else