cache bad folders requests for 30s. Suitcase can induce a ton of this, and viewers keep requesting

master
UbitUmarov 2020-07-16 18:23:17 +01:00
parent 7a55f82f74
commit ce92ee1057
6 changed files with 82 additions and 23 deletions

View File

@ -62,11 +62,12 @@ namespace OpenSim.Capabilities.Handlers
m_Scene = s;
}
public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests)
{
//m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
List<LLSDFetchInventoryDescendents> folders = null;
List<UUID> bad_folders = new List<UUID>();
try
{
OSDArray foldersrequested = null;
@ -83,12 +84,19 @@ namespace OpenSim.Capabilities.Handlers
folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
for (int i = 0; i < foldersrequested.Count; i++)
{
OSDMap mfolder = foldersrequested[i] as OSDMap;
UUID id = mfolder["folder_id"].AsUUID();
if(BadRequests.ContainsKey(id))
{
bad_folders.Add(id);
}
else
{
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
try
{
OSDMap mfolder = (OSDMap)foldersrequested[i];
llsdRequest.folder_id = mfolder["folder_id"].AsUUID();
llsdRequest.folder_id = id;
llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
@ -101,6 +109,7 @@ namespace OpenSim.Capabilities.Handlers
}
folders.Add(llsdRequest);
}
}
foldersrequested = null;
tmp = null;
}
@ -112,12 +121,23 @@ namespace OpenSim.Capabilities.Handlers
}
if (folders == null || folders.Count == 0)
{
if(bad_folders.Count == 0)
{
httpResponse.RawBuffer = EmptyResponse;
return;
}
List<UUID> bad_folders = new List<UUID>();
StringBuilder sb = osStringBuilderCache.Acquire();
sb.Append("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
{
sb.Append("<map><key>folder_id</key><uuid>");
sb.Append(bad.ToString());
sb.Append("</uuid><key>error</key><string>Unknown</string></map>");
}
sb.Append("</array></map></llsd>");
httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
}
int total_folders = 0;
int total_items = 0;
@ -206,6 +226,7 @@ namespace OpenSim.Capabilities.Handlers
lastresponse.Append("<map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
{
BadRequests.Add(bad);
lastresponse.Append("<map><key>folder_id</key><uuid>");
lastresponse.Append(bad.ToString());
lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");

View File

@ -29,9 +29,12 @@ using System;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Capabilities.Handlers
{
@ -67,9 +70,15 @@ namespace OpenSim.Capabilities.Handlers
m_LibraryService =
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
ISimpleStreamHandler reqHandler
= new SimpleStreamHandler( "/CAPS/WebFetchInvDesc/", webFetchHandler.FetchInventoryDescendentsRequest);
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
});
server.AddSimpleStreamHandler(reqHandler);
}
}

View File

@ -108,22 +108,31 @@ namespace OpenSim.Capabilities.Handlers
return LLSDxmlEncode.End(lsl);
}
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap)
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
{
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
if(BadRequests == null)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
OSDArray itemsRequested = (OSDArray)requestmap["items"];
UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0;
foreach (OSDMap osdItemId in itemsRequested)
{
itemIDs[i++] = osdItemId["item_id"].AsUUID();
UUID id = osdItemId["item_id"].AsUUID();
if(!BadRequests.ContainsKey(id))
itemIDs[i++] = id;
}
InventoryItemBase[] items = null;
try
{
// badrequests still not filled
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
}
catch{ }

View File

@ -131,10 +131,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
{
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
using(ExpiringKey<UUID> bad = new ExpiringKey<UUID>(5000)) // bad but this is test
using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
{
req.InputStream = ms;
handler.FetchInventoryDescendentsRequest(req, resp);
handler.FetchInventoryDescendentsRequest(req, resp, bad);
}
return Util.UTF8.GetString(resp.RawBuffer);
}

View File

@ -28,7 +28,9 @@
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Capabilities.Handlers;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@ -53,6 +55,7 @@ namespace OpenSim.Region.ClientStack.Linden
private IInventoryService m_inventoryService = null;
private ILibraryService m_LibraryService = null;
private string m_fetchInventory2Url;
private ExpiringKey<UUID> m_badRequests;
#region ISharedRegionModule Members
@ -83,6 +86,8 @@ namespace OpenSim.Region.ClientStack.Linden
{
m_inventoryService = null;
m_LibraryService = null;
m_badRequests.Dispose();
m_badRequests = null;
}
}
@ -96,6 +101,9 @@ namespace OpenSim.Region.ClientStack.Linden
if(m_LibraryService == null)
m_LibraryService = s.LibraryService;
if(m_badRequests == null)
m_badRequests = new ExpiringKey<UUID>(30000);
if (m_inventoryService != null)
{
s.EventManager.OnRegisterCaps += RegisterCaps;
@ -122,7 +130,11 @@ namespace OpenSim.Region.ClientStack.Linden
{
FetchInventory2Handler fetchHandler = new FetchInventory2Handler(m_inventoryService, agentID);
caps.RegisterSimpleHandler("FetchInventory2",
new SimpleOSDMapHandler("POST", "/" + UUID.Random(), fetchHandler.FetchInventorySimpleRequest));
new SimpleOSDMapHandler("POST", "/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
{
fetchHandler.FetchInventorySimpleRequest(httpRequest, httpResponse, map, m_badRequests);
}
));
}
else
{

View File

@ -37,6 +37,7 @@ using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@ -90,6 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden
private ILibraryService m_LibraryService;
private bool m_Enabled;
private ExpiringKey<UUID> m_badRequests;
private string m_fetchInventoryDescendents2Url;
// private string m_webFetchInventoryDescendentsUrl;
@ -193,6 +195,9 @@ namespace OpenSim.Region.ClientStack.Linden
Scene.EventManager.OnRegisterCaps += RegisterCaps;
if(m_badRequests == null)
m_badRequests = new ExpiringKey<UUID>(30000);
m_NumberScenes++;
int nworkers = 2; // was 2
@ -231,6 +236,8 @@ namespace OpenSim.Region.ClientStack.Linden
Watchdog.AbortThread(t.ManagedThreadId);
m_workerThreads = null;
m_badRequests.Dispose();
m_badRequests = null;
}
}
// m_queue.Dispose();
@ -331,7 +338,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
OSHttpResponse osresponse = new OSHttpResponse(requestinfo.request);
m_webFetchHandler.FetchInventoryDescendentsRequest(requestinfo.request, osresponse);
m_webFetchHandler.FetchInventoryDescendentsRequest(requestinfo.request, osresponse, m_module.m_badRequests);
requestinfo.request.InputStream.Dispose();
lock (responses)