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.cs831
1 files changed, 831 insertions, 0 deletions
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
new file mode 100644
index 0000000..e7d38c2
--- /dev/null
+++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
@@ -0,0 +1,831 @@
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 groupID, 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 {
410 m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
411
412 // also remove this list
413 if (m_Cache.Contains("roles-" + groupID.ToString()))
414 m_Cache.Remove("roles-" + groupID.ToString());
415
416 }
417
418 return true;
419 }
420
421 return false;
422 }
423
424 public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
425 {
426 if (d())
427 {
428 object role;
429 lock (m_Cache)
430 if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
431 {
432 GroupRolesData r = (GroupRolesData)role;
433 r.Description = description;
434 r.Name = name;
435 r.Powers = powers;
436 r.Title = title;
437
438 m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
439 }
440 return true;
441 }
442 else
443 {
444 lock (m_Cache)
445 {
446 if (m_Cache.Contains("role-" + roleID.ToString()))
447 m_Cache.Remove("role-" + roleID.ToString());
448
449 // also remove these lists, because they will have an outdated role
450 if (m_Cache.Contains("roles-" + groupID.ToString()))
451 m_Cache.Remove("roles-" + groupID.ToString());
452
453 }
454
455 return false;
456 }
457 }
458
459 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
460 {
461 d();
462
463 lock (m_Cache)
464 {
465 if (m_Cache.Contains("role-" + roleID.ToString()))
466 m_Cache.Remove("role-" + roleID.ToString());
467
468 // also remove the list, because it will have an removed role
469 if (m_Cache.Contains("roles-" + groupID.ToString()))
470 m_Cache.Remove("roles-" + groupID.ToString());
471
472 if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
473 m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
474
475 if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
476 m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
477 }
478 }
479
480 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
481 {
482 object roles = null;
483 bool firstCall = false;
484 string cacheKey = "roles-" + GroupID.ToString();
485
486 while (true)
487 {
488 lock (m_Cache)
489 {
490 if (m_Cache.TryGetValue(cacheKey, out roles))
491 return (List<GroupRolesData>)roles;
492
493 // not cached
494 if (!m_ActiveRequests.ContainsKey(cacheKey))
495 {
496 m_ActiveRequests.Add(cacheKey, true);
497 firstCall = true;
498 }
499 }
500
501 if (firstCall)
502 {
503 roles = d();
504 if (roles != null)
505 {
506 lock (m_Cache)
507 {
508 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
509 m_ActiveRequests.Remove(cacheKey);
510 return (List<GroupRolesData>)roles;
511 }
512 }
513 }
514 else
515 Thread.Sleep(50);
516 }
517 }
518
519 public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
520 {
521 object rmembers = null;
522 bool firstCall = false;
523 // we need to key in also on the requester, because different ppl have different view privileges
524 string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
525
526 //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
527 while (true)
528 {
529 lock (m_Cache)
530 {
531 if (m_Cache.TryGetValue(cacheKey, out rmembers))
532 {
533 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
534 return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
535 }
536
537 // not cached
538 if (!m_ActiveRequests.ContainsKey(cacheKey))
539 {
540 m_ActiveRequests.Add(cacheKey, true);
541 firstCall = true;
542 }
543 }
544
545 if (firstCall)
546 {
547 List<ExtendedGroupRoleMembersData> _rmembers = d();
548
549 if (_rmembers != null && _rmembers.Count > 0)
550 rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
551 else
552 rmembers = new List<GroupRoleMembersData>();
553
554 lock (m_Cache)
555 {
556 // For some strange reason, when I cache the list of GroupRoleMembersData,
557 // it gets emptied out. The TryGet gets an empty list...
558 //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
559 // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
560 // I don't get it.
561 m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
562 m_ActiveRequests.Remove(cacheKey);
563 return (List<GroupRoleMembersData>)rmembers;
564 }
565 }
566 else
567 Thread.Sleep(50);
568 }
569 }
570
571 public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
572 {
573 if (d())
574 {
575 lock (m_Cache)
576 {
577 // update the cached role
578 string cacheKey = "role-" + RoleID.ToString();
579 object obj;
580 if (m_Cache.TryGetValue(cacheKey, out obj))
581 {
582 GroupRolesData r = (GroupRolesData)obj;
583 r.Members++;
584 }
585
586 // add this agent to the list of role members
587 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
588 if (m_Cache.TryGetValue(cacheKey, out obj))
589 {
590 try
591 {
592 // This may throw an exception, in which case the agentID is not a UUID but a full ID
593 // In that case, let's just remove the whoe things from the cache
594 UUID id = new UUID(AgentID);
595 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
596 List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
597 GroupRoleMembersData rm = new GroupRoleMembersData();
598 rm.MemberID = id;
599 rm.RoleID = RoleID;
600 rmlist.Add(rm);
601 }
602 catch
603 {
604 m_Cache.Remove(cacheKey);
605 }
606 }
607
608 // Remove the cached info about this agent's roles
609 // because we don't have enough local info about the new role
610 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
611 if (m_Cache.Contains(cacheKey))
612 m_Cache.Remove(cacheKey);
613
614 }
615 }
616 }
617
618 public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
619 {
620 if (d())
621 {
622 lock (m_Cache)
623 {
624 // update the cached role
625 string cacheKey = "role-" + RoleID.ToString();
626 object obj;
627 if (m_Cache.TryGetValue(cacheKey, out obj))
628 {
629 GroupRolesData r = (GroupRolesData)obj;
630 r.Members--;
631 }
632
633 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
634 if (m_Cache.Contains(cacheKey))
635 m_Cache.Remove(cacheKey);
636
637 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
638 if (m_Cache.Contains(cacheKey))
639 m_Cache.Remove(cacheKey);
640 }
641 }
642 }
643
644 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
645 {
646 object roles = null;
647 bool firstCall = false;
648 string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
649
650 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
651
652 while (true)
653 {
654 lock (m_Cache)
655 {
656 if (m_Cache.TryGetValue(cacheKey, out roles))
657 {
658 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
659 return (List<GroupRolesData>)roles;
660 }
661
662 // not cached
663 if (!m_ActiveRequests.ContainsKey(cacheKey))
664 {
665 m_ActiveRequests.Add(cacheKey, true);
666 firstCall = true;
667 }
668 }
669
670 if (firstCall)
671 {
672 roles = d();
673 lock (m_Cache)
674 {
675 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
676 m_ActiveRequests.Remove(cacheKey);
677 return (List<GroupRolesData>)roles;
678 }
679 }
680 else
681 Thread.Sleep(50);
682 }
683 }
684
685 public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
686 {
687 d();
688
689 lock (m_Cache)
690 {
691 // Invalidate cached info, because it has ActiveRoleID and Powers
692 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
693 if (m_Cache.Contains(cacheKey))
694 m_Cache.Remove(cacheKey);
695
696 cacheKey = "memberships-" + AgentID.ToString();
697 if (m_Cache.Contains(cacheKey))
698 m_Cache.Remove(cacheKey);
699 }
700 }
701
702 public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
703 {
704 d();
705
706 lock (m_Cache)
707 {
708 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
709 if (m_Cache.Contains(cacheKey))
710 m_Cache.Remove(cacheKey);
711
712 cacheKey = "memberships-" + AgentID.ToString();
713 if (m_Cache.Contains(cacheKey))
714 m_Cache.Remove(cacheKey);
715
716 cacheKey = "active-" + AgentID.ToString();
717 object m = null;
718 if (m_Cache.TryGetValue(cacheKey, out m))
719 {
720 GroupMembershipData membership = (GroupMembershipData)m;
721 membership.ListInProfile = ListInProfile;
722 membership.AcceptNotices = AcceptNotices;
723 }
724 }
725 }
726
727 public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
728 {
729 if (d())
730 {
731 lock (m_Cache)
732 {
733 m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
734 string cacheKey = "notices-" + groupID.ToString();
735 if (m_Cache.Contains(cacheKey))
736 m_Cache.Remove(cacheKey);
737
738 }
739
740 return true;
741 }
742
743 return false;
744 }
745
746 public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
747 {
748 object notice = null;
749 bool firstCall = false;
750 string cacheKey = "notice-" + noticeID.ToString();
751
752 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
753
754 while (true)
755 {
756 lock (m_Cache)
757 {
758 if (m_Cache.TryGetValue(cacheKey, out notice))
759 {
760 return (GroupNoticeInfo)notice;
761 }
762
763 // not cached
764 if (!m_ActiveRequests.ContainsKey(cacheKey))
765 {
766 m_ActiveRequests.Add(cacheKey, true);
767 firstCall = true;
768 }
769 }
770
771 if (firstCall)
772 {
773 GroupNoticeInfo _notice = d();
774
775 lock (m_Cache)
776 {
777 m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
778 m_ActiveRequests.Remove(cacheKey);
779 return _notice;
780 }
781 }
782 else
783 Thread.Sleep(50);
784 }
785 }
786
787 public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
788 {
789 object notices = null;
790 bool firstCall = false;
791 string cacheKey = "notices-" + GroupID.ToString();
792
793 //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
794
795 while (true)
796 {
797 lock (m_Cache)
798 {
799 if (m_Cache.TryGetValue(cacheKey, out notices))
800 {
801 //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
802 return (List<ExtendedGroupNoticeData>)notices;
803 }
804
805 // not cached
806 if (!m_ActiveRequests.ContainsKey(cacheKey))
807 {
808 m_ActiveRequests.Add(cacheKey, true);
809 firstCall = true;
810 }
811 }
812
813 if (firstCall)
814 {
815 notices = d();
816
817 lock (m_Cache)
818 {
819 m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
820 m_ActiveRequests.Remove(cacheKey);
821 return (List<ExtendedGroupNoticeData>)notices;
822 }
823 }
824 else
825 Thread.Sleep(50);
826 }
827 }
828
829
830 }
831}