aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs')
-rw-r--r--OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs824
1 files changed, 824 insertions, 0 deletions
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
new file mode 100644
index 0000000..f789626
--- /dev/null
+++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
@@ -0,0 +1,824 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35
36using OpenMetaverse;
37
38namespace OpenSim.Groups
39{
40 public delegate ExtendedGroupRecord GroupRecordDelegate();
41 public delegate GroupMembershipData GroupMembershipDelegate();
42 public delegate List<GroupMembershipData> GroupMembershipListDelegate();
43 public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate();
44 public delegate List<GroupRolesData> GroupRolesListDelegate();
45 public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate();
46 public delegate GroupNoticeInfo NoticeDelegate();
47 public delegate List<ExtendedGroupNoticeData> NoticeListDelegate();
48 public delegate void VoidDelegate();
49 public delegate bool BooleanDelegate();
50
51 public class RemoteConnectorCacheWrapper
52 {
53 private ForeignImporter m_ForeignImporter;
54
55 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
56 private const int GROUPS_CACHE_TIMEOUT = 5 * 60; // 5 minutes
57
58 // This all important cache cahces objects of different types:
59 // group-<GroupID> or group-<Name> => ExtendedGroupRecord
60 // active-<AgentID> => GroupMembershipData
61 // membership-<AgentID>-<GroupID> => GroupMembershipData
62 // memberships-<AgentID> => List<GroupMembershipData>
63 // members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData>
64 // role-<RoleID> => GroupRolesData
65 // roles-<GroupID> => List<GroupRolesData> ; all roles in the group
66 // roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has
67 // rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData>
68 // notice-<noticeID> => GroupNoticeInfo
69 // notices-<GroupID> => List<ExtendedGroupNoticeData>
70 private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>();
71
72 public RemoteConnectorCacheWrapper(IUserManagement uman)
73 {
74 m_ForeignImporter = new ForeignImporter(uman);
75 }
76
77 public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
78 {
79 //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
80 //reason = string.Empty;
81
82 //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
83 // membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
84 ExtendedGroupRecord group = d();
85
86 if (group == null)
87 return UUID.Zero;
88
89 if (group.GroupID != UUID.Zero)
90 lock (m_Cache)
91 {
92 m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
93 if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
94 m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
95 }
96
97 return group.GroupID;
98 }
99
100 public bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
101 {
102 //reason = string.Empty;
103 //ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
104 ExtendedGroupRecord group = d();
105
106 if (group != null && group.GroupID != UUID.Zero)
107 lock (m_Cache)
108 m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
109 return true;
110 }
111
112 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
113 {
114 //if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
115 // return null;
116
117 object group = null;
118 bool firstCall = false;
119 string cacheKey = "group-";
120 if (GroupID != UUID.Zero)
121 cacheKey += GroupID.ToString();
122 else
123 cacheKey += GroupName;
124
125 //m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey);
126
127 while (true)
128 {
129 lock (m_Cache)
130 {
131 if (m_Cache.TryGetValue(cacheKey, out group))
132 {
133 //m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey);
134 return (ExtendedGroupRecord)group;
135 }
136
137 // not cached
138 if (!m_ActiveRequests.ContainsKey(cacheKey))
139 {
140 m_ActiveRequests.Add(cacheKey, true);
141 firstCall = true;
142 }
143 }
144
145 if (firstCall)
146 {
147 //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
148 group = d();
149
150 lock (m_Cache)
151 {
152 m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
153 m_ActiveRequests.Remove(cacheKey);
154 return (ExtendedGroupRecord)group;
155 }
156 }
157 else
158 Thread.Sleep(50);
159 }
160 }
161
162 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
163 {
164 GroupMembershipData membership = d();
165 if (membership == null)
166 return false;
167
168 lock (m_Cache)
169 {
170 // first, remove everything! add a user is a heavy-duty op
171 m_Cache.Clear();
172
173 m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
174 m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
175 }
176
177
178 return true;
179 }
180
181 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
182 {
183 d();
184
185 lock (m_Cache)
186 {
187 string cacheKey = "active-" + AgentID.ToString();
188 if (m_Cache.Contains(cacheKey))
189 m_Cache.Remove(cacheKey);
190
191 cacheKey = "memberships-" + AgentID.ToString();
192 if (m_Cache.Contains(cacheKey))
193 m_Cache.Remove(cacheKey);
194
195 cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
196 if (m_Cache.Contains(cacheKey))
197 m_Cache.Remove(cacheKey);
198
199 cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
200 if (m_Cache.Contains(cacheKey))
201 m_Cache.Remove(cacheKey);
202
203 cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString();
204 if (m_Cache.Contains(cacheKey))
205 m_Cache.Remove(cacheKey);
206 }
207 }
208
209 public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
210 {
211 GroupMembershipData activeGroup = d();
212 if (activeGroup != null)
213 {
214 string cacheKey = "active-" + AgentID.ToString();
215 lock (m_Cache)
216 if (m_Cache.Contains(cacheKey))
217 m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
218 }
219 }
220
221 public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
222 {
223 object membership = null;
224 bool firstCall = false;
225 string cacheKey = "active-" + AgentID.ToString();
226
227 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
228
229 while (true)
230 {
231 lock (m_Cache)
232 {
233 if (m_Cache.TryGetValue(cacheKey, out membership))
234 {
235 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
236 return (ExtendedGroupMembershipData)membership;
237 }
238
239 // not cached
240 if (!m_ActiveRequests.ContainsKey(cacheKey))
241 {
242 m_ActiveRequests.Add(cacheKey, true);
243 firstCall = true;
244 }
245 }
246
247 if (firstCall)
248 {
249 membership = d();
250
251 lock (m_Cache)
252 {
253 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
254 m_ActiveRequests.Remove(cacheKey);
255 return (ExtendedGroupMembershipData)membership;
256 }
257 }
258 else
259 Thread.Sleep(50);
260 }
261
262 }
263
264 public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)
265 {
266 object membership = null;
267 bool firstCall = false;
268 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
269
270 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
271
272 while (true)
273 {
274 lock (m_Cache)
275 {
276 if (m_Cache.TryGetValue(cacheKey, out membership))
277 {
278 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
279 return (ExtendedGroupMembershipData)membership;
280 }
281
282 // not cached
283 if (!m_ActiveRequests.ContainsKey(cacheKey))
284 {
285 m_ActiveRequests.Add(cacheKey, true);
286 firstCall = true;
287 }
288 }
289
290 if (firstCall)
291 {
292 membership = d();
293 lock (m_Cache)
294 {
295 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
296 m_ActiveRequests.Remove(cacheKey);
297 return (ExtendedGroupMembershipData)membership;
298 }
299 }
300 else
301 Thread.Sleep(50);
302 }
303 }
304
305 public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
306 {
307 object memberships = null;
308 bool firstCall = false;
309 string cacheKey = "memberships-" + AgentID.ToString();
310
311 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
312
313 while (true)
314 {
315 lock (m_Cache)
316 {
317 if (m_Cache.TryGetValue(cacheKey, out memberships))
318 {
319 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
320 return (List<GroupMembershipData>)memberships;
321 }
322
323 // not cached
324 if (!m_ActiveRequests.ContainsKey(cacheKey))
325 {
326 m_ActiveRequests.Add(cacheKey, true);
327 firstCall = true;
328 }
329 }
330
331 if (firstCall)
332 {
333 memberships = d();
334 lock (m_Cache)
335 {
336 m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
337 m_ActiveRequests.Remove(cacheKey);
338 return (List<GroupMembershipData>)memberships;
339 }
340 }
341 else
342 Thread.Sleep(50);
343 }
344 }
345
346 public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
347 {
348 object members = null;
349 bool firstCall = false;
350 // we need to key in also on the requester, because different ppl have different view privileges
351 string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
352
353 //m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
354
355 while (true)
356 {
357 lock (m_Cache)
358 {
359 if (m_Cache.TryGetValue(cacheKey, out members))
360 {
361 List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
362 return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
363 }
364
365 // not cached
366 if (!m_ActiveRequests.ContainsKey(cacheKey))
367 {
368 m_ActiveRequests.Add(cacheKey, true);
369 firstCall = true;
370 }
371 }
372
373 if (firstCall)
374 {
375 List<ExtendedGroupMembersData> _members = d();
376
377 if (_members != null && _members.Count > 0)
378 members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
379 else
380 members = new List<GroupMembersData>();
381
382 lock (m_Cache)
383 {
384 //m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
385 m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
386 m_ActiveRequests.Remove(cacheKey);
387
388 return (List<GroupMembersData>)members;
389 }
390 }
391 else
392 Thread.Sleep(50);
393 }
394 }
395
396 public bool AddGroupRole(UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
397 {
398 if (d())
399 {
400 GroupRolesData role = new GroupRolesData();
401 role.Description = description;
402 role.Members = 0;
403 role.Name = name;
404 role.Powers = powers;
405 role.RoleID = roleID;
406 role.Title = title;
407
408 lock (m_Cache)
409 m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
410
411 return true;
412 }
413
414 return false;
415 }
416
417 public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
418 {
419 if (d())
420 {
421 object role;
422 lock (m_Cache)
423 if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
424 {
425 GroupRolesData r = (GroupRolesData)role;
426 r.Description = description;
427 r.Name = name;
428 r.Powers = powers;
429 r.Title = title;
430
431 m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
432 }
433 return true;
434 }
435 else
436 {
437 lock (m_Cache)
438 {
439 if (m_Cache.Contains("role-" + roleID.ToString()))
440 m_Cache.Remove("role-" + roleID.ToString());
441
442 // also remove these lists, because they will have an outdated role
443 if (m_Cache.Contains("roles-" + groupID.ToString()))
444 m_Cache.Remove("roles-" + groupID.ToString());
445
446 }
447
448 return false;
449 }
450 }
451
452 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
453 {
454 d();
455
456 lock (m_Cache)
457 {
458 if (m_Cache.Contains("role-" + roleID.ToString()))
459 m_Cache.Remove("role-" + roleID.ToString());
460
461 // also remove the list, because it will have an removed role
462 if (m_Cache.Contains("roles-" + groupID.ToString()))
463 m_Cache.Remove("roles-" + groupID.ToString());
464
465 if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
466 m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
467
468 if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
469 m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
470 }
471 }
472
473 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
474 {
475 object roles = null;
476 bool firstCall = false;
477 string cacheKey = "roles-" + GroupID.ToString();
478
479 while (true)
480 {
481 lock (m_Cache)
482 {
483 if (m_Cache.TryGetValue(cacheKey, out roles))
484 return (List<GroupRolesData>)roles;
485
486 // not cached
487 if (!m_ActiveRequests.ContainsKey(cacheKey))
488 {
489 m_ActiveRequests.Add(cacheKey, true);
490 firstCall = true;
491 }
492 }
493
494 if (firstCall)
495 {
496 roles = d();
497 if (roles != null)
498 {
499 lock (m_Cache)
500 {
501 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
502 m_ActiveRequests.Remove(cacheKey);
503 return (List<GroupRolesData>)roles;
504 }
505 }
506 }
507 else
508 Thread.Sleep(50);
509 }
510 }
511
512 public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
513 {
514 object rmembers = null;
515 bool firstCall = false;
516 // we need to key in also on the requester, because different ppl have different view privileges
517 string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
518
519 //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
520 while (true)
521 {
522 lock (m_Cache)
523 {
524 if (m_Cache.TryGetValue(cacheKey, out rmembers))
525 {
526 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
527 return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
528 }
529
530 // not cached
531 if (!m_ActiveRequests.ContainsKey(cacheKey))
532 {
533 m_ActiveRequests.Add(cacheKey, true);
534 firstCall = true;
535 }
536 }
537
538 if (firstCall)
539 {
540 List<ExtendedGroupRoleMembersData> _rmembers = d();
541
542 if (_rmembers != null && _rmembers.Count > 0)
543 rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
544 else
545 rmembers = new List<GroupRoleMembersData>();
546
547 lock (m_Cache)
548 {
549 // For some strange reason, when I cache the list of GroupRoleMembersData,
550 // it gets emptied out. The TryGet gets an empty list...
551 //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
552 // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
553 // I don't get it.
554 m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
555 m_ActiveRequests.Remove(cacheKey);
556 return (List<GroupRoleMembersData>)rmembers;
557 }
558 }
559 else
560 Thread.Sleep(50);
561 }
562 }
563
564 public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
565 {
566 if (d())
567 {
568 lock (m_Cache)
569 {
570 // update the cached role
571 string cacheKey = "role-" + RoleID.ToString();
572 object obj;
573 if (m_Cache.TryGetValue(cacheKey, out obj))
574 {
575 GroupRolesData r = (GroupRolesData)obj;
576 r.Members++;
577 }
578
579 // add this agent to the list of role members
580 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
581 if (m_Cache.TryGetValue(cacheKey, out obj))
582 {
583 try
584 {
585 // This may throw an exception, in which case the agentID is not a UUID but a full ID
586 // In that case, let's just remove the whoe things from the cache
587 UUID id = new UUID(AgentID);
588 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
589 List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
590 GroupRoleMembersData rm = new GroupRoleMembersData();
591 rm.MemberID = id;
592 rm.RoleID = RoleID;
593 rmlist.Add(rm);
594 }
595 catch
596 {
597 m_Cache.Remove(cacheKey);
598 }
599 }
600
601 // Remove the cached info about this agent's roles
602 // because we don't have enough local info about the new role
603 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
604 if (m_Cache.Contains(cacheKey))
605 m_Cache.Remove(cacheKey);
606
607 }
608 }
609 }
610
611 public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
612 {
613 if (d())
614 {
615 lock (m_Cache)
616 {
617 // update the cached role
618 string cacheKey = "role-" + RoleID.ToString();
619 object obj;
620 if (m_Cache.TryGetValue(cacheKey, out obj))
621 {
622 GroupRolesData r = (GroupRolesData)obj;
623 r.Members--;
624 }
625
626 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
627 if (m_Cache.Contains(cacheKey))
628 m_Cache.Remove(cacheKey);
629
630 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
631 if (m_Cache.Contains(cacheKey))
632 m_Cache.Remove(cacheKey);
633 }
634 }
635 }
636
637 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
638 {
639 object roles = null;
640 bool firstCall = false;
641 string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
642
643 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
644
645 while (true)
646 {
647 lock (m_Cache)
648 {
649 if (m_Cache.TryGetValue(cacheKey, out roles))
650 {
651 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
652 return (List<GroupRolesData>)roles;
653 }
654
655 // not cached
656 if (!m_ActiveRequests.ContainsKey(cacheKey))
657 {
658 m_ActiveRequests.Add(cacheKey, true);
659 firstCall = true;
660 }
661 }
662
663 if (firstCall)
664 {
665 roles = d();
666 lock (m_Cache)
667 {
668 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
669 m_ActiveRequests.Remove(cacheKey);
670 return (List<GroupRolesData>)roles;
671 }
672 }
673 else
674 Thread.Sleep(50);
675 }
676 }
677
678 public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
679 {
680 d();
681
682 lock (m_Cache)
683 {
684 // Invalidate cached info, because it has ActiveRoleID and Powers
685 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
686 if (m_Cache.Contains(cacheKey))
687 m_Cache.Remove(cacheKey);
688
689 cacheKey = "memberships-" + AgentID.ToString();
690 if (m_Cache.Contains(cacheKey))
691 m_Cache.Remove(cacheKey);
692 }
693 }
694
695 public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
696 {
697 d();
698
699 lock (m_Cache)
700 {
701 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
702 if (m_Cache.Contains(cacheKey))
703 m_Cache.Remove(cacheKey);
704
705 cacheKey = "memberships-" + AgentID.ToString();
706 if (m_Cache.Contains(cacheKey))
707 m_Cache.Remove(cacheKey);
708
709 cacheKey = "active-" + AgentID.ToString();
710 object m = null;
711 if (m_Cache.TryGetValue(cacheKey, out m))
712 {
713 GroupMembershipData membership = (GroupMembershipData)m;
714 membership.ListInProfile = ListInProfile;
715 membership.AcceptNotices = AcceptNotices;
716 }
717 }
718 }
719
720 public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
721 {
722 if (d())
723 {
724 lock (m_Cache)
725 {
726 m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
727 string cacheKey = "notices-" + groupID.ToString();
728 if (m_Cache.Contains(cacheKey))
729 m_Cache.Remove(cacheKey);
730
731 }
732
733 return true;
734 }
735
736 return false;
737 }
738
739 public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
740 {
741 object notice = null;
742 bool firstCall = false;
743 string cacheKey = "notice-" + noticeID.ToString();
744
745 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
746
747 while (true)
748 {
749 lock (m_Cache)
750 {
751 if (m_Cache.TryGetValue(cacheKey, out notice))
752 {
753 return (GroupNoticeInfo)notice;
754 }
755
756 // not cached
757 if (!m_ActiveRequests.ContainsKey(cacheKey))
758 {
759 m_ActiveRequests.Add(cacheKey, true);
760 firstCall = true;
761 }
762 }
763
764 if (firstCall)
765 {
766 GroupNoticeInfo _notice = d();
767
768 lock (m_Cache)
769 {
770 m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
771 m_ActiveRequests.Remove(cacheKey);
772 return _notice;
773 }
774 }
775 else
776 Thread.Sleep(50);
777 }
778 }
779
780 public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
781 {
782 object notices = null;
783 bool firstCall = false;
784 string cacheKey = "notices-" + GroupID.ToString();
785
786 //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
787
788 while (true)
789 {
790 lock (m_Cache)
791 {
792 if (m_Cache.TryGetValue(cacheKey, out notices))
793 {
794 //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
795 return (List<ExtendedGroupNoticeData>)notices;
796 }
797
798 // not cached
799 if (!m_ActiveRequests.ContainsKey(cacheKey))
800 {
801 m_ActiveRequests.Add(cacheKey, true);
802 firstCall = true;
803 }
804 }
805
806 if (firstCall)
807 {
808 notices = d();
809
810 lock (m_Cache)
811 {
812 m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
813 m_ActiveRequests.Remove(cacheKey);
814 return (List<ExtendedGroupNoticeData>)notices;
815 }
816 }
817 else
818 Thread.Sleep(50);
819 }
820 }
821
822
823 }
824}