From 2cac56340a079fad8a16736778b6ebef78fb6d56 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 18 Aug 2015 21:03:34 +0100 Subject: [PATCH] try to serialize http requests from same connection, so they are processed in order. ( next commits will be about necessary keepAlive changes needed) --- .../HttpServer/PollServiceHttpRequest.cs | 38 +++++++++++++++ .../HttpServer/PollServiceRequestManager.cs | 46 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 6aa94794ee..e636c38569 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Text; using HttpServer; @@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer public readonly IHttpRequest Request; public readonly int RequestTime; public readonly UUID RequestID; + public int contextHash; + + private void GenContextHash() + { + Random rnd = new Random(); + contextHash = 0; + if (Request.Headers["remote_addr"] != null) + contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16; + else + contextHash = rnd.Next() << 16; + if (Request.Headers["remote_port"] != null) + { + string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' }); + contextHash += Int32.Parse(strPorts[0]); + } + else + contextHash += rnd.Next() & 0xffff; + } public PollServiceHttpRequest( PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) @@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer Request = pRequest; RequestTime = System.Environment.TickCount; RequestID = UUID.Random(); + GenContextHash(); } internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) @@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; + response.ReuseContext = false; try { @@ -93,5 +114,22 @@ namespace OpenSim.Framework.Servers.HttpServer PollServiceArgs.RequestsHandled++; } } + + } + + class PollServiceHttpRequestComparer : IEqualityComparer + { + public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2) + { + if (b1.contextHash != b2.contextHash) + return false; + bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext); + return b; + } + + public int GetHashCode(PollServiceHttpRequest b2) + { + return (int)b2.contextHash; + } } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index e75b705eef..2c5c41d771 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -46,6 +46,7 @@ namespace OpenSim.Framework.Servers.HttpServer private readonly BaseHttpServer m_server; + private Dictionary> m_bycontext; private BlockingQueue m_requests = new BlockingQueue(); private static Queue m_slowRequests = new Queue(); private static Queue m_retryRequests = new Queue(); @@ -65,6 +66,9 @@ namespace OpenSim.Framework.Servers.HttpServer m_WorkerThreadCount = pWorkerThreadCount; m_workerThreads = new Thread[m_WorkerThreadCount]; + PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); + m_bycontext = new Dictionary>(preqCp); + STPStartInfo startInfo = new STPStartInfo(); startInfo.IdleTimeout = 30000; startInfo.MaxWorkerThreads = 15; @@ -113,6 +117,45 @@ namespace OpenSim.Framework.Servers.HttpServer } public void Enqueue(PollServiceHttpRequest req) + { + lock (m_bycontext) + { + Queue ctxQeueue; + if (m_bycontext.TryGetValue(req, out ctxQeueue)) + { + ctxQeueue.Enqueue(req); + } + else + { + ctxQeueue = new Queue(); + m_bycontext[req] = ctxQeueue; + EnqueueInt(req); + } + } + } + + public void byContextDequeue(PollServiceHttpRequest req) + { + Queue ctxQeueue; + lock (m_bycontext) + { + if (m_bycontext.TryGetValue(req, out ctxQeueue)) + { + if (ctxQeueue.Count > 0) + { + PollServiceHttpRequest newreq = ctxQeueue.Dequeue(); + EnqueueInt(newreq); + } + else + { + m_bycontext.Remove(req); + } + } + } + } + + + public void EnqueueInt(PollServiceHttpRequest req) { if (m_running) { @@ -220,6 +263,7 @@ namespace OpenSim.Framework.Servers.HttpServer try { req.DoHTTPGruntWork(m_server, responsedata); + byContextDequeue(req); } catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream { @@ -233,6 +277,7 @@ namespace OpenSim.Framework.Servers.HttpServer try { req.DoHTTPGruntWork(m_server, responsedata); + byContextDequeue(req); } catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream { @@ -249,6 +294,7 @@ namespace OpenSim.Framework.Servers.HttpServer { req.DoHTTPGruntWork(m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); + byContextDequeue(req); } else {