From 10ae5454cbc0bb5ffab518203023d76abdd762cd Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Tue, 14 Dec 2010 12:16:51 -0800
Subject: 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.
---
.../CoreModules/World/WorldMap/WorldMapModule.cs | 80 +++++++++++++++++++---
1 file changed, 71 insertions(+), 9 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 6d9afce..e3ba190 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -33,6 +33,7 @@ using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Reflection;
+using System.Runtime.Remoting.Messaging;
using System.Threading;
using log4net;
using Nini.Config;
@@ -413,11 +414,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
}
}
+ private int nAsyncRequests = 0;
///
/// Processing thread main() loop for doing remote mapitem requests
///
public void process()
{
+ const int MAX_ASYNC_REQUESTS = 20;
try
{
while (true)
@@ -437,10 +440,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
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);
- RequestMapItemsCompleted(response);
+ while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
+ 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
///
/// The OSDMap Response for the mapitem
- 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();
if (requestID != UUID.Zero)
@@ -538,6 +557,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
EnqueueMapItemRequest(st);
}
+ private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
+ uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
///
/// Does the actual remote mapitem request
/// This should be called from an asynchronous thread
@@ -552,9 +573,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
/// passed in from packet
/// Region we're looking up
///
- private OSDMap RequestMapItemsAsync(string httpserver, UUID id, uint flags,
+ private OSDMap RequestMapItemsAsync(UUID id, uint flags,
uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
{
+ string httpserver = "";
bool blacklisted = false;
lock (m_blacklistedregions)
{
@@ -638,7 +660,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
os = mapitemsrequest.GetRequestStream();
os.Write(buffer, 0, buffer.Length); //Send it
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)
{
@@ -654,15 +676,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
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;
{ // get the response
+ StreamReader sr = null;
try
{
WebResponse webResponse = mapitemsrequest.GetResponse();
if (webResponse != null)
{
- StreamReader sr = new StreamReader(webResponse.GetResponseStream());
+ sr = new StreamReader(webResponse.GetResponseStream());
response_mapItems_reply = sr.ReadToEnd().Trim();
}
else
@@ -683,6 +712,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
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;
try
{
@@ -691,14 +738,29 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
responseMap = (OSDMap)rezResponse;
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);
+ lock (m_blacklistedregions)
+ {
+ if (!m_blacklistedregions.ContainsKey(regionhandle))
+ m_blacklistedregions.Add(regionhandle, Environment.TickCount);
+ }
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;
}
--
cgit v1.1