aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2019-02-24 09:46:55 +0000
committerUbitUmarov2019-02-24 09:46:55 +0000
commitcd5a6daa84a153fdc3dc7cc3a65363b36d441b34 (patch)
treea320f9571c1829e6a6fa9f4ca4152b8b83370c43
parentseveral changes to llHttpRequest processing: options section renamed ScriptsH... (diff)
downloadopensim-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
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs152
-rw-r--r--OpenSim/Region/Framework/Interfaces/IHttpRequests.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2
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>();