aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
diff options
context:
space:
mode:
authorDiva Canto2013-07-17 11:19:36 -0700
committerDiva Canto2013-07-17 11:19:36 -0700
commite46459ef21e1ee5ceaeca70365a7c881d33b09ce (patch)
tree519428c7148d85f6d8b114710928fb41f2edbbfd /OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
parentRemoved the MapItems thread. Redirected the map items requests to the service... (diff)
downloadopensim-SC-e46459ef21e1ee5ceaeca70365a7c881d33b09ce.zip
opensim-SC-e46459ef21e1ee5ceaeca70365a7c881d33b09ce.tar.gz
opensim-SC-e46459ef21e1ee5ceaeca70365a7c881d33b09ce.tar.bz2
opensim-SC-e46459ef21e1ee5ceaeca70365a7c881d33b09ce.tar.xz
Cleared up much confusion in PollServiceRequestManager. Here's the history:
When Melanie added the web fetch inventory throttle to core, she made the long poll requests (EQs) effectively be handled on an active loop. All those requests, if they existed, were being constantly dequeued, checked for events (which most often they didn't have), and requeued again. This was an active loop thread on a 100ms cycle! This fixes the issue. Now the inventory requests, if they aren't ready to be served, are placed directly back in the queue, but the long poll requests aren't placed there until there are events ready to be sent or timeout has been reached. This puts the LongPollServiceWatcherThread back to 1sec cycle, as it was before.
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs79
1 files changed, 33 insertions, 46 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 1b9010a..4cb551c 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -47,12 +47,11 @@ namespace OpenSim.Framework.Servers.HttpServer
47 private readonly BaseHttpServer m_server; 47 private readonly BaseHttpServer m_server;
48 48
49 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); 49 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
50 private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); 50 private static Queue<PollServiceHttpRequest> m_longPollRequests = new Queue<PollServiceHttpRequest>();
51 private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
52 51
53 private uint m_WorkerThreadCount = 0; 52 private uint m_WorkerThreadCount = 0;
54 private Thread[] m_workerThreads; 53 private Thread[] m_workerThreads;
55 private Thread m_retrysThread; 54 private Thread m_longPollThread;
56 55
57 private bool m_running = true; 56 private bool m_running = true;
58 private int slowCount = 0; 57 private int slowCount = 0;
@@ -84,9 +83,9 @@ namespace OpenSim.Framework.Servers.HttpServer
84 int.MaxValue); 83 int.MaxValue);
85 } 84 }
86 85
87 m_retrysThread = Watchdog.StartThread( 86 m_longPollThread = Watchdog.StartThread(
88 this.CheckRetries, 87 this.CheckLongPollThreads,
89 string.Format("PollServiceWatcherThread:{0}", m_server.Port), 88 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
90 ThreadPriority.Normal, 89 ThreadPriority.Normal,
91 false, 90 false,
92 true, 91 true,
@@ -97,48 +96,47 @@ namespace OpenSim.Framework.Servers.HttpServer
97 private void ReQueueEvent(PollServiceHttpRequest req) 96 private void ReQueueEvent(PollServiceHttpRequest req)
98 { 97 {
99 if (m_running) 98 if (m_running)
100 { 99 m_requests.Enqueue(req);
101 lock (m_retryRequests)
102 m_retryRequests.Enqueue(req);
103 }
104 } 100 }
105 101
106 public void Enqueue(PollServiceHttpRequest req) 102 public void Enqueue(PollServiceHttpRequest req)
107 { 103 {
108 if (m_running) 104 if (m_running)
109 { 105 {
110 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal) 106 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
111 { 107 {
112 m_requests.Enqueue(req); 108 lock (m_longPollRequests)
109 m_longPollRequests.Enqueue(req);
113 } 110 }
114 else 111 else
115 { 112 m_requests.Enqueue(req);
116 lock (m_slowRequests)
117 m_slowRequests.Enqueue(req);
118 }
119 } 113 }
120 } 114 }
121 115
122 private void CheckRetries() 116 private void CheckLongPollThreads()
123 { 117 {
118 // The only purpose of this thread is to check the EQs for events.
119 // If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests.
120 // If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
121 // All other types of tasks (Inventory handlers) don't have the long-poll nature,
122 // so if they aren't ready to be served by a worker thread (no events), they are placed
123 // directly back in the "ready-to-serve" queue by the worker thread.
124 while (m_running) 124 while (m_running)
125 { 125 {
126 Thread.Sleep(100); // let the world move .. back to faster rate 126 Thread.Sleep(1000);
127 Watchdog.UpdateThread(); 127 Watchdog.UpdateThread();
128 lock (m_retryRequests)
129 {
130 while (m_retryRequests.Count > 0 && m_running)
131 m_requests.Enqueue(m_retryRequests.Dequeue());
132 }
133 slowCount++;
134 if (slowCount >= 10)
135 {
136 slowCount = 0;
137 128
138 lock (m_slowRequests) 129 PollServiceHttpRequest req;
130 lock (m_longPollRequests)
131 {
132 while (m_longPollRequests.Count > 0 && m_running)
139 { 133 {
140 while (m_slowRequests.Count > 0 && m_running) 134 req = m_longPollRequests.Dequeue();
141 m_requests.Enqueue(m_slowRequests.Dequeue()); 135 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ
136 (Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) // no events, but timeout
137 m_requests.Enqueue(req);
138 else
139 m_longPollRequests.Enqueue(req);
142 } 140 }
143 } 141 }
144 } 142 }
@@ -153,24 +151,12 @@ namespace OpenSim.Framework.Servers.HttpServer
153 foreach (Thread t in m_workerThreads) 151 foreach (Thread t in m_workerThreads)
154 Watchdog.AbortThread(t.ManagedThreadId); 152 Watchdog.AbortThread(t.ManagedThreadId);
155 153
156 try
157 {
158 foreach (PollServiceHttpRequest req in m_retryRequests)
159 {
160 req.DoHTTPGruntWork(m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
161 }
162 }
163 catch
164 {
165 }
166
167 PollServiceHttpRequest wreq; 154 PollServiceHttpRequest wreq;
168 m_retryRequests.Clear();
169 155
170 lock (m_slowRequests) 156 lock (m_longPollRequests)
171 { 157 {
172 while (m_slowRequests.Count > 0 && m_running) 158 while (m_longPollRequests.Count > 0 && m_running)
173 m_requests.Enqueue(m_slowRequests.Dequeue()); 159 m_requests.Enqueue(m_longPollRequests.Dequeue());
174 } 160 }
175 161
176 while (m_requests.Count() > 0) 162 while (m_requests.Count() > 0)
@@ -196,6 +182,7 @@ namespace OpenSim.Framework.Servers.HttpServer
196 while (m_running) 182 while (m_running)
197 { 183 {
198 PollServiceHttpRequest req = m_requests.Dequeue(5000); 184 PollServiceHttpRequest req = m_requests.Dequeue(5000);
185 //m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
199 186
200 Watchdog.UpdateThread(); 187 Watchdog.UpdateThread();
201 if (req != null) 188 if (req != null)
@@ -209,7 +196,7 @@ namespace OpenSim.Framework.Servers.HttpServer
209 if (responsedata == null) 196 if (responsedata == null)
210 continue; 197 continue;
211 198
212 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue 199 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
213 { 200 {
214 try 201 try
215 { 202 {