aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs71
1 files changed, 63 insertions, 8 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 42008da..130513d 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized; 31using System.Collections.Specialized;
32using System.Reflection; 32using System.Reflection;
33using System.Threading;
33 34
34using Nwc.XmlRpc; 35using Nwc.XmlRpc;
35 36
@@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
167 168
168 private bool m_debugEnabled = false; 169 private bool m_debugEnabled = false;
169 170
171 private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
172
170 private ExpiringCache<string, OSDMap> m_memoryCache; 173 private ExpiringCache<string, OSDMap> m_memoryCache;
171 private int m_cacheTimeout = 30; 174 private int m_cacheTimeout = 30;
172 175
@@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1348 // Immediately forward the request if the cache is disabled. 1351 // Immediately forward the request if the cache is disabled.
1349 if (m_cacheTimeout == 0) 1352 if (m_cacheTimeout == 0)
1350 { 1353 {
1354 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled");
1351 return WebUtil.PostToService(m_groupsServerURI, requestArgs); 1355 return WebUtil.PostToService(m_groupsServerURI, requestArgs);
1352 } 1356 }
1353 1357
@@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1355 if (requestArgs["RequestMethod"] == "RemoveGeneric" 1359 if (requestArgs["RequestMethod"] == "RemoveGeneric"
1356 || requestArgs["RequestMethod"] == "AddGeneric") 1360 || requestArgs["RequestMethod"] == "AddGeneric")
1357 { 1361 {
1362 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
1363
1358 // Any and all updates cause the cache to clear 1364 // Any and all updates cause the cache to clear
1359 m_memoryCache.Clear(); 1365 m_memoryCache.Clear();
1360 1366
@@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1366 1372
1367 // Create the cache key for the request and see if we have it cached 1373 // Create the cache key for the request and see if we have it cached
1368 string CacheKey = WebUtil.BuildQueryString(requestArgs); 1374 string CacheKey = WebUtil.BuildQueryString(requestArgs);
1369 OSDMap response = null; 1375
1370 if (!m_memoryCache.TryGetValue(CacheKey, out response)) 1376 // This code uses a leader/follower pattern. On a cache miss, the request is added
1377 // to a queue; the first thread to add it to the queue completes the request while
1378 // follow on threads busy wait for the results, this situation seems to happen
1379 // often when checking permissions
1380 while (true)
1371 { 1381 {
1372 // if it wasn't in the cache, pass the request to the Simian Grid Services 1382 OSDMap response = null;
1373 response = WebUtil.PostToService(m_groupsServerURI, requestArgs); 1383 bool firstRequest = false;
1374 1384
1375 // and cache the response 1385 lock (m_memoryCache)
1376 m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); 1386 {
1387 if (m_memoryCache.TryGetValue(CacheKey, out response))
1388 return response;
1389
1390 if (! m_pendingRequests.ContainsKey(CacheKey))
1391 {
1392 m_pendingRequests.Add(CacheKey,true);
1393 firstRequest = true;
1394 }
1395 }
1396
1397 if (firstRequest)
1398 {
1399 // if it wasn't in the cache, pass the request to the Simian Grid Services
1400 try
1401 {
1402 response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1403 }
1404 catch (Exception e)
1405 {
1406 m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey);
1407 }
1408
1409 // and cache the response
1410 lock (m_memoryCache)
1411 {
1412 m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1413 m_pendingRequests.Remove(CacheKey);
1414 }
1415
1416 return response;
1417 }
1418
1419 Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable
1377 } 1420 }
1378 1421
1379 // return cached response 1422 // if (!m_memoryCache.TryGetValue(CacheKey, out response))
1380 return response; 1423 // {
1424 // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
1425 // Util.PrintCallStack();
1426
1427 // // if it wasn't in the cache, pass the request to the Simian Grid Services
1428 // response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1429
1430 // // and cache the response
1431 // m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1432 // }
1433
1434 // // return cached response
1435 // return response;
1381 } 1436 }
1382 #endregion 1437 #endregion
1383 1438