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

View File

@ -29,9 +29,12 @@ using System;
using Nini.Config; using Nini.Config;
using OpenSim.Server.Base; using OpenSim.Server.Base;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base; using OpenSim.Server.Handlers.Base;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Capabilities.Handlers namespace OpenSim.Capabilities.Handlers
{ {
@ -67,9 +70,15 @@ namespace OpenSim.Capabilities.Handlers
m_LibraryService = m_LibraryService =
ServerUtils.LoadPlugin<ILibraryService>(libService, args); ServerUtils.LoadPlugin<ILibraryService>(libService, args);
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null); FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
ISimpleStreamHandler reqHandler 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); server.AddSimpleStreamHandler(reqHandler);
} }
} }

View File

@ -108,22 +108,31 @@ namespace OpenSim.Capabilities.Handlers
return LLSDxmlEncode.End(lsl); 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); //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"]; OSDArray itemsRequested = (OSDArray)requestmap["items"];
UUID[] itemIDs = new UUID[itemsRequested.Count]; UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0; int i = 0;
foreach (OSDMap osdItemId in itemsRequested) 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; InventoryItemBase[] items = null;
try try
{ {
// badrequests still not filled
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
} }
catch{ } catch{ }

View File

@ -131,10 +131,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
{ {
TestOSHttpRequest req = new TestOSHttpRequest(); TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse(); 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)) using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
{ {
req.InputStream = ms; req.InputStream = ms;
handler.FetchInventoryDescendentsRequest(req, resp); handler.FetchInventoryDescendentsRequest(req, resp, bad);
} }
return Util.UTF8.GetString(resp.RawBuffer); return Util.UTF8.GetString(resp.RawBuffer);
} }

View File

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

View File

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