add a Drop method to PollService Event handlers, Drop requests on connections known to be lost or delay event check if they are sending a response

httptests
UbitUmarov 2016-07-17 13:20:56 +01:00
parent 6a02ac634b
commit 442b272228
8 changed files with 126 additions and 44 deletions

View File

@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console
string uri = "/ReadResponses/" + sessionID.ToString() + "/"; string uri = "/ReadResponses/" + sessionID.ToString() + "/";
m_Server.AddPollServiceHTTPHandler( m_Server.AddPollServiceHTTPHandler(
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, Drop, sessionID, 25000)); // 25 secs timeout
XmlDocument xmldoc = new XmlDocument(); XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
@ -425,6 +425,15 @@ namespace OpenSim.Framework.Console
return false; return false;
} }
private void Drop(UUID RequestID, UUID sessionID)
{
lock (m_Connections)
{
if (m_Connections.ContainsKey(sessionID))
m_Connections.Remove(sessionID);
}
}
private Hashtable GetEvents(UUID RequestID, UUID sessionID) private Hashtable GetEvents(UUID RequestID, UUID sessionID)
{ {
ConsoleConnection c = null; ConsoleConnection c = null;

View File

@ -37,6 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId);
public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId);
public delegate void DropMethod(UUID requestID, UUID pId);
public class PollServiceEventArgs : EventArgs public class PollServiceEventArgs : EventArgs
{ {
@ -44,6 +45,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public GetEventsMethod GetEvents; public GetEventsMethod GetEvents;
public NoEventsMethod NoEvents; public NoEventsMethod NoEvents;
public RequestMethod Request; public RequestMethod Request;
public DropMethod Drop;
public UUID Id; public UUID Id;
public int TimeOutms; public int TimeOutms;
public EventType Type; public EventType Type;
@ -73,13 +75,14 @@ namespace OpenSim.Framework.Servers.HttpServer
RequestMethod pRequest, RequestMethod pRequest,
string pUrl, string pUrl,
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
UUID pId, int pTimeOutms) DropMethod pDrop, UUID pId, int pTimeOutms)
{ {
Request = pRequest; Request = pRequest;
Url = pUrl; Url = pUrl;
HasEvents = pHasEvents; HasEvents = pHasEvents;
GetEvents = pGetEvents; GetEvents = pGetEvents;
NoEvents = pNoEvents; NoEvents = pNoEvents;
Drop = pDrop;
Id = pId; Id = pId;
TimeOutms = pTimeOutms; TimeOutms = pTimeOutms;
Type = EventType.LongPoll; Type = EventType.LongPoll;

View File

@ -160,6 +160,19 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public void DropByContext(PollServiceHttpRequest req)
{
Queue<PollServiceHttpRequest> ctxQeueue;
lock (m_bycontext)
{
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{
ctxQeueue.Clear();
m_bycontext.Remove(req);
}
}
}
public void EnqueueInt(PollServiceHttpRequest req) public void EnqueueInt(PollServiceHttpRequest req)
{ {
if (m_running) if (m_running)
@ -263,22 +276,61 @@ namespace OpenSim.Framework.Servers.HttpServer
PollServiceHttpRequest req = m_requests.Dequeue(5000); PollServiceHttpRequest req = m_requests.Dequeue(5000);
Watchdog.UpdateThread(); Watchdog.UpdateThread();
if (req != null) if(req == null)
{ continue;
try
{
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
try
{
if(!req.HttpContext.CanSend())
{
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
byContextDequeue(req);
continue;
}
if(req.HttpContext.IsSending())
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
byContextDequeue(req);
}
else
ReQueueEvent(req);
continue;
}
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
m_threadPool.QueueWorkItem(x =>
{
try
{
req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
return null;
}, null);
}
else
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
m_threadPool.QueueWorkItem(x => m_threadPool.QueueWorkItem(x =>
{ {
try try
{ {
req.DoHTTPGruntWork(m_server, responsedata); req.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
byContextDequeue(req); byContextDequeue(req);
} }
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream catch (ObjectDisposedException)
{ {
// Ignore it, no need to reply // Ignore it, no need to reply
} }
@ -287,36 +339,15 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
else else
{ {
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) ReQueueEvent(req);
{
m_threadPool.QueueWorkItem(x =>
{
try
{
req.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
byContextDequeue(req);
}
catch (ObjectDisposedException)
{
// Ignore it, no need to reply
}
return null;
}, null);
}
else
{
ReQueueEvent(req);
}
} }
} }
catch (Exception e) }
{ catch (Exception e)
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); {
} m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
} }
} }
} }
} }
} }

View File

@ -372,7 +372,7 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterPollHandler( caps.RegisterPollHandler(
"EventQueueGet", "EventQueueGet",
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS));
} }
public bool HasEvents(UUID requestID, UUID agentID) public bool HasEvents(UUID requestID, UUID agentID)
@ -403,6 +403,10 @@ namespace OpenSim.Region.ClientStack.Linden
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name); ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
} }
} }
public void Drop(UUID requestID, UUID pAgentId)
{
// do nothing for now, hope client close will do it
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId) public Hashtable GetEvents(UUID requestID, UUID pAgentId)
{ {

View File

@ -226,7 +226,7 @@ namespace OpenSim.Region.ClientStack.Linden
private Scene m_scene; private Scene m_scene;
private MeshCapsDataThrottler m_throttler; private MeshCapsDataThrottler m_throttler;
public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
base(null, uri, null, null, null, pId, int.MaxValue) base(null, uri, null, null, null, null, pId, int.MaxValue)
{ {
m_scene = scene; m_scene = scene;
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
@ -241,6 +241,15 @@ namespace OpenSim.Region.ClientStack.Linden
} }
}; };
Drop= (x, y) =>
{
lock (responses)
{
responses.Remove(x);
}
};
GetEvents = (x, y) => GetEvents = (x, y) =>
{ {
lock (responses) lock (responses)

View File

@ -222,7 +222,7 @@ namespace OpenSim.Region.ClientStack.Linden
private Scene m_scene; private Scene m_scene;
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
public PollServiceTextureEventArgs(UUID pId, Scene scene) : public PollServiceTextureEventArgs(UUID pId, Scene scene) :
base(null, "", null, null, null, pId, int.MaxValue) base(null, "", null, null, null, null, pId, int.MaxValue)
{ {
m_scene = scene; m_scene = scene;
// x is request id, y is userid // x is request id, y is userid
@ -236,6 +236,9 @@ namespace OpenSim.Region.ClientStack.Linden
} }
}; };
Drop = (x, y) => { lock (responses) responses.Remove(x); };
GetEvents = (x, y) => GetEvents = (x, y) =>
{ {
lock (responses) lock (responses)
@ -423,7 +426,6 @@ namespace OpenSim.Region.ClientStack.Linden
internal sealed class CapsDataThrottler internal sealed class CapsDataThrottler
{ {
private volatile int currenttime = 0; private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0; private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0; private volatile int BytesSent = 0;

View File

@ -256,11 +256,13 @@ namespace OpenSim.Region.ClientStack.Linden
private WebFetchInvDescModule m_module; private WebFetchInvDescModule m_module;
public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) :
base(null, url, null, null, null, pId, int.MaxValue) base(null, url, null, null, null, null, pId, int.MaxValue)
{ {
m_module = module; m_module = module;
HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
Drop = (x, y) => { lock (responses) responses.Remove(x); };
GetEvents = (x, y) => GetEvents = (x, y) =>
{ {
lock (responses) lock (responses)

View File

@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
string uri = "/lslhttp/" + urlcode.ToString() + "/"; string uri = "/lslhttp/" + urlcode.ToString() + "/";
PollServiceEventArgs args PollServiceEventArgs args
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000);
args.Type = PollServiceEventArgs.EventType.LslHttp; args.Type = PollServiceEventArgs.EventType.LslHttp;
m_HttpServer.AddPollServiceHTTPHandler(uri, args); m_HttpServer.AddPollServiceHTTPHandler(uri, args);
@ -276,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
string uri = "/lslhttps/" + urlcode.ToString() + "/"; string uri = "/lslhttps/" + urlcode.ToString() + "/";
PollServiceEventArgs args PollServiceEventArgs args
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000);
args.Type = PollServiceEventArgs.EventType.LslHttp; args.Type = PollServiceEventArgs.EventType.LslHttp;
m_HttpsServer.AddPollServiceHTTPHandler(uri, args); m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
@ -530,6 +530,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
} }
} }
} }
private void Drop(UUID requestID, UUID sessionID)
{
UrlData url = null;
lock (m_RequestMap)
{
if (m_RequestMap.ContainsKey(requestID))
{
url = m_RequestMap[requestID];
m_RequestMap.Remove(requestID);
if(url != null)
{
lock (url.requests)
{
if(url.requests.ContainsKey(requestID))
url.requests.Remove(requestID);
}
}
}
}
}
private Hashtable GetEvents(UUID requestID, UUID sessionID) private Hashtable GetEvents(UUID requestID, UUID sessionID)
{ {
UrlData url = null; UrlData url = null;