diff options
author | UbitUmarov | 2019-02-24 09:46:55 +0000 |
---|---|---|
committer | UbitUmarov | 2019-02-24 09:46:55 +0000 |
commit | cd5a6daa84a153fdc3dc7cc3a65363b36d441b34 (patch) | |
tree | a320f9571c1829e6a6fa9f4ca4152b8b83370c43 | |
parent | several changes to llHttpRequest processing: options section renamed ScriptsH... (diff) | |
download | opensim-SC-cd5a6daa84a153fdc3dc7cc3a65363b36d441b34.zip opensim-SC-cd5a6daa84a153fdc3dc7cc3a65363b36d441b34.tar.gz opensim-SC-cd5a6daa84a153fdc3dc7cc3a65363b36d441b34.tar.bz2 opensim-SC-cd5a6daa84a153fdc3dc7cc3a65363b36d441b34.tar.xz |
also throttle llhttprequest by owner, options: PrimOwnerRequestsBurst = 5, PrimOwnerRequestsPerSec = 25; increase concurrency to 8
3 files changed, 86 insertions, 70 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 54936a3..83d91c4 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -95,16 +95,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
95 | { | 95 | { |
96 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 96 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
97 | 97 | ||
98 | private object HttpListLock = new object(); | 98 | private object m_httpListLock = new object(); |
99 | private int httpTimeout = 30000; | 99 | private int m_httpTimeout = 30000; |
100 | private string m_name = "HttpScriptRequests"; | 100 | private string m_name = "HttpScriptRequests"; |
101 | 101 | ||
102 | private OutboundUrlFilter m_outboundUrlFilter; | 102 | private OutboundUrlFilter m_outboundUrlFilter; |
103 | private string m_proxyurl = ""; | 103 | private string m_proxyurl = ""; |
104 | private string m_proxyexcepts = ""; | 104 | private string m_proxyexcepts = ""; |
105 | 105 | ||
106 | private float m_primpersec = 1.0f; | 106 | private float m_primPerSec = 1.0f; |
107 | private float m_primburst = 3f; | 107 | private float m_primBurst = 3.0f; |
108 | private float m_primOwnerPerSec = 25.0f; | ||
109 | private float m_primOwnerBurst = 5.0f; | ||
108 | 110 | ||
109 | private struct ThrottleData | 111 | private struct ThrottleData |
110 | { | 112 | { |
@@ -116,8 +118,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
116 | private Dictionary<UUID, HttpRequestClass> m_pendingRequests; | 118 | private Dictionary<UUID, HttpRequestClass> m_pendingRequests; |
117 | private ConcurrentQueue<HttpRequestClass> m_CompletedRequests; | 119 | private ConcurrentQueue<HttpRequestClass> m_CompletedRequests; |
118 | private ConcurrentDictionary<uint, ThrottleData> m_RequestsThrottle; | 120 | private ConcurrentDictionary<uint, ThrottleData> m_RequestsThrottle; |
121 | private ConcurrentDictionary<UUID, ThrottleData> m_OwnerRequestsThrottle; | ||
119 | 122 | ||
120 | private Scene m_scene; | ||
121 | public static SmartThreadPool ThreadPool = null; | 123 | public static SmartThreadPool ThreadPool = null; |
122 | 124 | ||
123 | public HttpRequestModule() | 125 | public HttpRequestModule() |
@@ -131,38 +133,64 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
131 | return UUID.Zero; | 133 | return UUID.Zero; |
132 | } | 134 | } |
133 | 135 | ||
134 | public bool CheckThrottle(uint localID) | 136 | public bool CheckThrottle(uint localID, UUID ownerID) |
135 | { | 137 | { |
136 | ThrottleData th; | 138 | ThrottleData th; |
137 | double now = Util.GetTimeStamp(); | 139 | double now = Util.GetTimeStamp(); |
138 | bool ret = false; | 140 | bool ret; |
139 | 141 | ||
140 | if (m_RequestsThrottle.TryGetValue(localID, out th)) | 142 | if (m_RequestsThrottle.TryGetValue(localID, out th)) |
141 | { | 143 | { |
142 | double delta = now - th.lastTime; | 144 | double delta = now - th.lastTime; |
143 | th.lastTime = now; | 145 | th.lastTime = now; |
144 | 146 | ||
145 | float add = (float)(m_primpersec * delta); | 147 | float add = (float)(m_primPerSec * delta); |
146 | th.count += add; | 148 | th.count += add; |
147 | if (th.count > m_primburst) | 149 | if (th.count > m_primBurst) |
148 | th.count = m_primburst; | 150 | th.count = m_primBurst; |
149 | 151 | ||
150 | ret = th.count > 0; | 152 | ret = th.count > 0; |
153 | if (ret) | ||
154 | th.count--; | ||
151 | } | 155 | } |
152 | else | 156 | else |
153 | { | 157 | { |
154 | th = new ThrottleData() | 158 | th = new ThrottleData() |
155 | { | 159 | { |
156 | lastTime = now, | 160 | lastTime = now, |
157 | count = m_primburst | 161 | count = m_primBurst - 1 |
158 | }; | 162 | }; |
159 | ret = true; | 163 | ret = true; |
160 | } | 164 | } |
165 | m_RequestsThrottle[localID] = th; | ||
161 | 166 | ||
162 | if (ret) | 167 | if(!ret) |
163 | th.count--; | 168 | return false; |
169 | |||
170 | if (m_OwnerRequestsThrottle.TryGetValue(ownerID, out th)) | ||
171 | { | ||
172 | double delta = now - th.lastTime; | ||
173 | th.lastTime = now; | ||
174 | |||
175 | float add = (float)(m_primOwnerPerSec * delta); | ||
176 | th.count += add; | ||
177 | if (th.count > m_primOwnerBurst) | ||
178 | th.count = m_primOwnerBurst; | ||
179 | |||
180 | ret = th.count > 0; | ||
181 | if (ret) | ||
182 | th.count--; | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | th = new ThrottleData() | ||
187 | { | ||
188 | lastTime = now, | ||
189 | count = m_primOwnerBurst - 1 | ||
190 | }; | ||
191 | } | ||
192 | m_OwnerRequestsThrottle[ownerID] = th; | ||
164 | 193 | ||
165 | m_RequestsThrottle[localID] = th; | ||
166 | return ret; | 194 | return ret; |
167 | } | 195 | } |
168 | 196 | ||
@@ -170,6 +198,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
170 | uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body, | 198 | uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body, |
171 | out HttpInitialRequestStatus status) | 199 | out HttpInitialRequestStatus status) |
172 | { | 200 | { |
201 | if (!CheckAllowed(new Uri(url))) | ||
202 | { | ||
203 | status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; | ||
204 | return UUID.Zero; | ||
205 | } | ||
206 | |||
173 | UUID reqID = UUID.Random(); | 207 | UUID reqID = UUID.Random(); |
174 | HttpRequestClass htc = new HttpRequestClass(); | 208 | HttpRequestClass htc = new HttpRequestClass(); |
175 | 209 | ||
@@ -254,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
254 | htc.ItemID = itemID; | 288 | htc.ItemID = itemID; |
255 | htc.Url = url; | 289 | htc.Url = url; |
256 | htc.ReqID = reqID; | 290 | htc.ReqID = reqID; |
257 | htc.HttpTimeout = httpTimeout; | 291 | htc.HttpTimeout = m_httpTimeout; |
258 | htc.OutboundBody = body; | 292 | htc.OutboundBody = body; |
259 | htc.ResponseHeaders = headers; | 293 | htc.ResponseHeaders = headers; |
260 | htc.proxyurl = m_proxyurl; | 294 | htc.proxyurl = m_proxyurl; |
@@ -263,16 +297,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
263 | // Same number as default HttpWebRequest.MaximumAutomaticRedirections | 297 | // Same number as default HttpWebRequest.MaximumAutomaticRedirections |
264 | htc.MaxRedirects = 50; | 298 | htc.MaxRedirects = 50; |
265 | 299 | ||
266 | if (StartHttpRequest(htc)) | 300 | lock (m_httpListLock) |
267 | { | 301 | m_pendingRequests.Add(reqID, htc); |
268 | status = HttpInitialRequestStatus.OK; | 302 | |
269 | return htc.ReqID; | 303 | htc.Process(); |
270 | } | 304 | status = HttpInitialRequestStatus.OK; |
271 | else | 305 | return reqID; |
272 | { | ||
273 | status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; | ||
274 | return UUID.Zero; | ||
275 | } | ||
276 | } | 306 | } |
277 | 307 | ||
278 | /// <summary> | 308 | /// <summary> |
@@ -284,37 +314,21 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
284 | return m_outboundUrlFilter.CheckAllowed(url); | 314 | return m_outboundUrlFilter.CheckAllowed(url); |
285 | } | 315 | } |
286 | 316 | ||
287 | public bool StartHttpRequest(HttpRequestClass req) | ||
288 | { | ||
289 | if (!CheckAllowed(new Uri(req.Url))) | ||
290 | return false; | ||
291 | |||
292 | lock (HttpListLock) | ||
293 | m_pendingRequests.Add(req.ReqID, req); | ||
294 | |||
295 | req.Process(); | ||
296 | |||
297 | return true; | ||
298 | } | ||
299 | |||
300 | public void StopHttpRequest(uint m_localID, UUID m_itemID) | 317 | public void StopHttpRequest(uint m_localID, UUID m_itemID) |
301 | { | 318 | { |
302 | if (m_pendingRequests != null) | 319 | List<UUID> toremove = new List<UUID>(); |
320 | lock (m_httpListLock) | ||
303 | { | 321 | { |
304 | List<UUID> toremove = new List<UUID>(); | 322 | foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) |
305 | lock (HttpListLock) | ||
306 | { | 323 | { |
307 | foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) | 324 | if(tmpReq.ItemID == m_itemID) |
308 | { | 325 | { |
309 | if(tmpReq.ItemID == m_itemID) | 326 | tmpReq.Stop(); |
310 | { | 327 | toremove.Add(tmpReq.ReqID); |
311 | tmpReq.Stop(); | ||
312 | toremove.Add(tmpReq.ReqID); | ||
313 | } | ||
314 | } | 328 | } |
315 | foreach(UUID id in toremove) | ||
316 | m_pendingRequests.Remove(id); | ||
317 | } | 329 | } |
330 | foreach(UUID id in toremove) | ||
331 | m_pendingRequests.Remove(id); | ||
318 | } | 332 | } |
319 | } | 333 | } |
320 | 334 | ||
@@ -328,10 +342,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
328 | */ | 342 | */ |
329 | public void GotCompletedRequest(HttpRequestClass req) | 343 | public void GotCompletedRequest(HttpRequestClass req) |
330 | { | 344 | { |
331 | if(req.Removed) | 345 | lock (m_httpListLock) |
332 | return; | ||
333 | lock (HttpListLock) | ||
334 | { | 346 | { |
347 | if (req.Removed) | ||
348 | return; | ||
335 | m_pendingRequests.Remove(req.ReqID); | 349 | m_pendingRequests.Remove(req.ReqID); |
336 | m_CompletedRequests.Enqueue(req); | 350 | m_CompletedRequests.Enqueue(req); |
337 | } | 351 | } |
@@ -340,17 +354,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
340 | public IServiceRequest GetNextCompletedRequest() | 354 | public IServiceRequest GetNextCompletedRequest() |
341 | { | 355 | { |
342 | HttpRequestClass req; | 356 | HttpRequestClass req; |
343 | while(m_CompletedRequests.TryDequeue(out req)) | 357 | if(m_CompletedRequests.TryDequeue(out req)) |
344 | { | 358 | return req; |
345 | if(!req.Removed) | 359 | |
346 | return req; | ||
347 | } | ||
348 | return null; | 360 | return null; |
349 | } | 361 | } |
350 | 362 | ||
351 | public void RemoveCompletedRequest(UUID reqId) | 363 | public void RemoveCompletedRequest(UUID reqId) |
352 | { | 364 | { |
353 | lock (HttpListLock) | 365 | lock (m_httpListLock) |
354 | { | 366 | { |
355 | HttpRequestClass tmpReq; | 367 | HttpRequestClass tmpReq; |
356 | if (m_pendingRequests.TryGetValue(reqId, out tmpReq)) | 368 | if (m_pendingRequests.TryGetValue(reqId, out tmpReq)) |
@@ -374,18 +386,26 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
374 | 386 | ||
375 | m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); | 387 | m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); |
376 | 388 | ||
377 | int maxThreads = 5; | 389 | int maxThreads = 8; |
378 | IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"]; | 390 | IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"]; |
379 | if (httpConfig != null) | 391 | if (httpConfig != null) |
380 | { | 392 | { |
381 | maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); | 393 | maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); |
382 | m_primburst = httpConfig.GetFloat("PrimRequestsBurst", m_primburst); | 394 | m_primBurst = httpConfig.GetFloat("PrimRequestsBurst", m_primBurst); |
383 | m_primpersec = httpConfig.GetFloat("PrimRequestsPerSec", m_primpersec); | 395 | m_primPerSec = httpConfig.GetFloat("PrimRequestsPerSec", m_primPerSec); |
396 | m_primOwnerBurst = httpConfig.GetFloat("PrimOwnerRequestsBurst", m_primOwnerBurst); | ||
397 | m_primOwnerPerSec = httpConfig.GetFloat("PrimOwnerRequestsPerSec", m_primOwnerPerSec); | ||
398 | m_httpTimeout = httpConfig.GetInt("RequestsTimeOut", m_httpTimeout); | ||
399 | if(m_httpTimeout > 60000) | ||
400 | m_httpTimeout = 60000; | ||
401 | else if(m_httpTimeout < 200) | ||
402 | m_httpTimeout = 200; | ||
384 | } | 403 | } |
385 | 404 | ||
386 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); | 405 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); |
387 | m_CompletedRequests = new ConcurrentQueue<HttpRequestClass>(); | 406 | m_CompletedRequests = new ConcurrentQueue<HttpRequestClass>(); |
388 | m_RequestsThrottle = new ConcurrentDictionary<uint, ThrottleData>(); | 407 | m_RequestsThrottle = new ConcurrentDictionary<uint, ThrottleData>(); |
408 | m_OwnerRequestsThrottle = new ConcurrentDictionary<UUID, ThrottleData>(); | ||
389 | 409 | ||
390 | // First instance sets this up for all sims | 410 | // First instance sets this up for all sims |
391 | if (ThreadPool == null) | 411 | if (ThreadPool == null) |
@@ -405,16 +425,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
405 | 425 | ||
406 | public void AddRegion(Scene scene) | 426 | public void AddRegion(Scene scene) |
407 | { | 427 | { |
408 | m_scene = scene; | 428 | scene.RegisterModuleInterface<IHttpRequestModule>(this); |
409 | |||
410 | m_scene.RegisterModuleInterface<IHttpRequestModule>(this); | ||
411 | } | 429 | } |
412 | 430 | ||
413 | public void RemoveRegion(Scene scene) | 431 | public void RemoveRegion(Scene scene) |
414 | { | 432 | { |
415 | scene.UnregisterModuleInterface<IHttpRequestModule>(this); | 433 | scene.UnregisterModuleInterface<IHttpRequestModule>(this); |
416 | if (scene == m_scene) | ||
417 | m_scene = null; | ||
418 | } | 434 | } |
419 | 435 | ||
420 | public void PostInitialise() | 436 | public void PostInitialise() |
@@ -570,6 +586,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
570 | 586 | ||
571 | Request.AllowAutoRedirect = false; | 587 | Request.AllowAutoRedirect = false; |
572 | Request.KeepAlive = false; | 588 | Request.KeepAlive = false; |
589 | Request.Timeout = HttpTimeout; | ||
573 | 590 | ||
574 | //This works around some buggy HTTP Servers like Lighttpd | 591 | //This works around some buggy HTTP Servers like Lighttpd |
575 | Request.ServicePoint.Expect100Continue = false; | 592 | Request.ServicePoint.Expect100Continue = false; |
@@ -629,7 +646,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
629 | bstream.Write(data, 0, data.Length); | 646 | bstream.Write(data, 0, data.Length); |
630 | } | 647 | } |
631 | 648 | ||
632 | Request.Timeout = HttpTimeout; | ||
633 | try | 649 | try |
634 | { | 650 | { |
635 | // execute the request | 651 | // execute the request |
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index 3ab1f6c..2c75844 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs | |||
@@ -87,6 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
87 | void StopHttpRequest(uint m_localID, UUID m_itemID); | 87 | void StopHttpRequest(uint m_localID, UUID m_itemID); |
88 | IServiceRequest GetNextCompletedRequest(); | 88 | IServiceRequest GetNextCompletedRequest(); |
89 | void RemoveCompletedRequest(UUID id); | 89 | void RemoveCompletedRequest(UUID id); |
90 | bool CheckThrottle(uint localID); | 90 | bool CheckThrottle(uint localID, UUID onerID); |
91 | } | 91 | } |
92 | } | 92 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6cea821..bb4bab0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -13950,7 +13950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13950 | if(httpScriptMod == null) | 13950 | if(httpScriptMod == null) |
13951 | return ""; | 13951 | return ""; |
13952 | 13952 | ||
13953 | if(!httpScriptMod.CheckThrottle(m_host.LocalId)) | 13953 | if(!httpScriptMod.CheckThrottle(m_host.LocalId, m_host.OwnerID)) |
13954 | return UUID.Zero.ToString(); | 13954 | return UUID.Zero.ToString(); |
13955 | 13955 | ||
13956 | List<string> param = new List<string>(); | 13956 | List<string> param = new List<string>(); |