Made the map thread request the map items asynchronously, as the name suggested -- but with a cap of 20 async requests max at any given time.

viewer-2-initial-appearance
Diva Canto 2010-12-14 12:16:51 -08:00
parent 4357288a94
commit 10ae5454cb
1 changed files with 71 additions and 9 deletions

View File

@ -33,6 +33,7 @@ using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Threading; using System.Threading;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
@ -413,11 +414,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
} }
} }
private int nAsyncRequests = 0;
/// <summary> /// <summary>
/// Processing thread main() loop for doing remote mapitem requests /// Processing thread main() loop for doing remote mapitem requests
/// </summary> /// </summary>
public void process() public void process()
{ {
const int MAX_ASYNC_REQUESTS = 20;
try try
{ {
while (true) while (true)
@ -437,10 +440,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
dorequest = false; dorequest = false;
} }
if (dorequest) if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
{ {
OSDMap response = RequestMapItemsAsync("", st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
RequestMapItemsCompleted(response); Thread.Sleep(80);
RequestMapItemsDelegate d = RequestMapItemsAsync;
d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
//OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
//RequestMapItemsCompleted(response);
Interlocked.Increment(ref nAsyncRequests);
} }
} }
@ -469,8 +478,18 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
/// Sends the mapitem response to the IClientAPI /// Sends the mapitem response to the IClientAPI
/// </summary> /// </summary>
/// <param name="response">The OSDMap Response for the mapitem</param> /// <param name="response">The OSDMap Response for the mapitem</param>
private void RequestMapItemsCompleted(OSDMap response) private void RequestMapItemsCompleted(IAsyncResult iar)
{ {
AsyncResult result = (AsyncResult)iar;
RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
OSDMap response = (OSDMap)icon.EndInvoke(iar);
Interlocked.Decrement(ref nAsyncRequests);
if (!response.ContainsKey("requestID"))
return;
UUID requestID = response["requestID"].AsUUID(); UUID requestID = response["requestID"].AsUUID();
if (requestID != UUID.Zero) if (requestID != UUID.Zero)
@ -538,6 +557,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
EnqueueMapItemRequest(st); EnqueueMapItemRequest(st);
} }
private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
/// <summary> /// <summary>
/// Does the actual remote mapitem request /// Does the actual remote mapitem request
/// This should be called from an asynchronous thread /// This should be called from an asynchronous thread
@ -552,9 +573,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
/// <param name="itemtype">passed in from packet</param> /// <param name="itemtype">passed in from packet</param>
/// <param name="regionhandle">Region we're looking up</param> /// <param name="regionhandle">Region we're looking up</param>
/// <returns></returns> /// <returns></returns>
private OSDMap RequestMapItemsAsync(string httpserver, UUID id, uint flags, private OSDMap RequestMapItemsAsync(UUID id, uint flags,
uint EstateID, bool godlike, uint itemtype, ulong regionhandle) uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
{ {
string httpserver = "";
bool blacklisted = false; bool blacklisted = false;
lock (m_blacklistedregions) lock (m_blacklistedregions)
{ {
@ -638,7 +660,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
os = mapitemsrequest.GetRequestStream(); os = mapitemsrequest.GetRequestStream();
os.Write(buffer, 0, buffer.Length); //Send it os.Write(buffer, 0, buffer.Length); //Send it
os.Close(); os.Close();
//m_log.DebugFormat("[WORLD MAP]: Getting MapItems from Sim {0}", httpserver); //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver);
} }
catch (WebException ex) catch (WebException ex)
{ {
@ -654,15 +676,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
return responseMap; return responseMap;
} }
catch
{
m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
responseMap["connect"] = OSD.FromBoolean(false);
return responseMap;
}
string response_mapItems_reply = null; string response_mapItems_reply = null;
{ // get the response { // get the response
StreamReader sr = null;
try try
{ {
WebResponse webResponse = mapitemsrequest.GetResponse(); WebResponse webResponse = mapitemsrequest.GetResponse();
if (webResponse != null) if (webResponse != null)
{ {
StreamReader sr = new StreamReader(webResponse.GetResponseStream()); sr = new StreamReader(webResponse.GetResponseStream());
response_mapItems_reply = sr.ReadToEnd().Trim(); response_mapItems_reply = sr.ReadToEnd().Trim();
} }
else else
@ -683,6 +712,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
return responseMap; return responseMap;
} }
catch
{
m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
responseMap["connect"] = OSD.FromBoolean(false);
lock (m_blacklistedregions)
{
if (!m_blacklistedregions.ContainsKey(regionhandle))
m_blacklistedregions.Add(regionhandle, Environment.TickCount);
}
return responseMap;
}
finally
{
if (sr != null)
sr.Close();
}
OSD rezResponse = null; OSD rezResponse = null;
try try
{ {
@ -691,14 +738,29 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
responseMap = (OSDMap)rezResponse; responseMap = (OSDMap)rezResponse;
responseMap["requestID"] = OSD.FromUUID(requestID); responseMap["requestID"] = OSD.FromUUID(requestID);
} }
catch (Exception) catch (Exception ex)
{ {
//m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message); m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
responseMap["connect"] = OSD.FromBoolean(false); responseMap["connect"] = OSD.FromBoolean(false);
lock (m_blacklistedregions)
{
if (!m_blacklistedregions.ContainsKey(regionhandle))
m_blacklistedregions.Add(regionhandle, Environment.TickCount);
}
return responseMap; return responseMap;
} }
} }
if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle
{
if (!m_blacklistedregions.ContainsKey(regionhandle))
{
m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting.");
m_blacklistedregions.Add(regionhandle, Environment.TickCount);
}
}
return responseMap; return responseMap;
} }