clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Threading;
32  
33 using OpenSim.Framework;
34 using OpenSim.Region.Framework.Interfaces;
35  
36 using OpenMetaverse;
37  
38 namespace 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 = 1 * 60; // 1 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 string cacheKey = "active-" + AgentID.ToString();
213 lock (m_Cache)
214 if (m_Cache.Contains(cacheKey))
215 m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
216 }
217  
218 public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
219 {
220 object membership = null;
221 bool firstCall = false;
222 string cacheKey = "active-" + AgentID.ToString();
223  
224 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
225  
226 while (true)
227 {
228 lock (m_Cache)
229 {
230 if (m_Cache.TryGetValue(cacheKey, out membership))
231 {
232 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
233 return (ExtendedGroupMembershipData)membership;
234 }
235  
236 // not cached
237 if (!m_ActiveRequests.ContainsKey(cacheKey))
238 {
239 m_ActiveRequests.Add(cacheKey, true);
240 firstCall = true;
241 }
242 }
243  
244 if (firstCall)
245 {
246 membership = d();
247  
248 lock (m_Cache)
249 {
250 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
251 m_ActiveRequests.Remove(cacheKey);
252 return (ExtendedGroupMembershipData)membership;
253 }
254 }
255 else
256 Thread.Sleep(50);
257 }
258  
259 }
260  
261 public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)
262 {
263 object membership = null;
264 bool firstCall = false;
265 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
266  
267 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
268  
269 while (true)
270 {
271 lock (m_Cache)
272 {
273 if (m_Cache.TryGetValue(cacheKey, out membership))
274 {
275 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
276 return (ExtendedGroupMembershipData)membership;
277 }
278  
279 // not cached
280 if (!m_ActiveRequests.ContainsKey(cacheKey))
281 {
282 m_ActiveRequests.Add(cacheKey, true);
283 firstCall = true;
284 }
285 }
286  
287 if (firstCall)
288 {
289 membership = d();
290 lock (m_Cache)
291 {
292 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
293 m_ActiveRequests.Remove(cacheKey);
294 return (ExtendedGroupMembershipData)membership;
295 }
296 }
297 else
298 Thread.Sleep(50);
299 }
300 }
301  
302 public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
303 {
304 object memberships = null;
305 bool firstCall = false;
306 string cacheKey = "memberships-" + AgentID.ToString();
307  
308 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
309  
310 while (true)
311 {
312 lock (m_Cache)
313 {
314 if (m_Cache.TryGetValue(cacheKey, out memberships))
315 {
316 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
317 return (List<GroupMembershipData>)memberships;
318 }
319  
320 // not cached
321 if (!m_ActiveRequests.ContainsKey(cacheKey))
322 {
323 m_ActiveRequests.Add(cacheKey, true);
324 firstCall = true;
325 }
326 }
327  
328 if (firstCall)
329 {
330 memberships = d();
331 lock (m_Cache)
332 {
333 m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
334 m_ActiveRequests.Remove(cacheKey);
335 return (List<GroupMembershipData>)memberships;
336 }
337 }
338 else
339 Thread.Sleep(50);
340 }
341 }
342  
343 public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
344 {
345 object members = null;
346 bool firstCall = false;
347 // we need to key in also on the requester, because different ppl have different view privileges
348 string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
349  
350 //m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
351  
352 while (true)
353 {
354 lock (m_Cache)
355 {
356 if (m_Cache.TryGetValue(cacheKey, out members))
357 {
358 List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
359 return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
360 }
361  
362 // not cached
363 if (!m_ActiveRequests.ContainsKey(cacheKey))
364 {
365 m_ActiveRequests.Add(cacheKey, true);
366 firstCall = true;
367 }
368 }
369  
370 if (firstCall)
371 {
372 List<ExtendedGroupMembersData> _members = d();
373  
374 if (_members != null && _members.Count > 0)
375 members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
376 else
377 members = new List<GroupMembersData>();
378  
379 lock (m_Cache)
380 {
381 //m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
382 m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
383 m_ActiveRequests.Remove(cacheKey);
384  
385 return (List<GroupMembersData>)members;
386 }
387 }
388 else
389 Thread.Sleep(50);
390 }
391 }
392  
393 public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
394 {
395 if (d())
396 {
397 GroupRolesData role = new GroupRolesData();
398 role.Description = description;
399 role.Members = 0;
400 role.Name = name;
401 role.Powers = powers;
402 role.RoleID = roleID;
403 role.Title = title;
404  
405 lock (m_Cache)
406 {
407 m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
408  
409 // also remove this list
410 if (m_Cache.Contains("roles-" + groupID.ToString()))
411 m_Cache.Remove("roles-" + groupID.ToString());
412  
413 }
414  
415 return true;
416 }
417  
418 return false;
419 }
420  
421 public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
422 {
423 if (d())
424 {
425 object role;
426 lock (m_Cache)
427 if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
428 {
429 GroupRolesData r = (GroupRolesData)role;
430 r.Description = description;
431 r.Name = name;
432 r.Powers = powers;
433 r.Title = title;
434  
435 m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
436 }
437 return true;
438 }
439 else
440 {
441 lock (m_Cache)
442 {
443 if (m_Cache.Contains("role-" + roleID.ToString()))
444 m_Cache.Remove("role-" + roleID.ToString());
445  
446 // also remove these lists, because they will have an outdated role
447 if (m_Cache.Contains("roles-" + groupID.ToString()))
448 m_Cache.Remove("roles-" + groupID.ToString());
449  
450 }
451  
452 return false;
453 }
454 }
455  
456 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
457 {
458 d();
459  
460 lock (m_Cache)
461 {
462 if (m_Cache.Contains("role-" + roleID.ToString()))
463 m_Cache.Remove("role-" + roleID.ToString());
464  
465 // also remove the list, because it will have an removed role
466 if (m_Cache.Contains("roles-" + groupID.ToString()))
467 m_Cache.Remove("roles-" + groupID.ToString());
468  
469 if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
470 m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
471  
472 if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
473 m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
474 }
475 }
476  
477 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
478 {
479 object roles = null;
480 bool firstCall = false;
481 string cacheKey = "roles-" + GroupID.ToString();
482  
483 while (true)
484 {
485 lock (m_Cache)
486 {
487 if (m_Cache.TryGetValue(cacheKey, out roles))
488 return (List<GroupRolesData>)roles;
489  
490 // not cached
491 if (!m_ActiveRequests.ContainsKey(cacheKey))
492 {
493 m_ActiveRequests.Add(cacheKey, true);
494 firstCall = true;
495 }
496 }
497  
498 if (firstCall)
499 {
500 roles = d();
501 if (roles != null)
502 {
503 lock (m_Cache)
504 {
505 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
506 m_ActiveRequests.Remove(cacheKey);
507 return (List<GroupRolesData>)roles;
508 }
509 }
510 }
511 else
512 Thread.Sleep(50);
513 }
514 }
515  
516 public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
517 {
518 object rmembers = null;
519 bool firstCall = false;
520 // we need to key in also on the requester, because different ppl have different view privileges
521 string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
522  
523 //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
524 while (true)
525 {
526 lock (m_Cache)
527 {
528 if (m_Cache.TryGetValue(cacheKey, out rmembers))
529 {
530 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
531 return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
532 }
533  
534 // not cached
535 if (!m_ActiveRequests.ContainsKey(cacheKey))
536 {
537 m_ActiveRequests.Add(cacheKey, true);
538 firstCall = true;
539 }
540 }
541  
542 if (firstCall)
543 {
544 List<ExtendedGroupRoleMembersData> _rmembers = d();
545  
546 if (_rmembers != null && _rmembers.Count > 0)
547 rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
548 else
549 rmembers = new List<GroupRoleMembersData>();
550  
551 lock (m_Cache)
552 {
553 // For some strange reason, when I cache the list of GroupRoleMembersData,
554 // it gets emptied out. The TryGet gets an empty list...
555 //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
556 // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
557 // I don't get it.
558 m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
559 m_ActiveRequests.Remove(cacheKey);
560 return (List<GroupRoleMembersData>)rmembers;
561 }
562 }
563 else
564 Thread.Sleep(50);
565 }
566 }
567  
568 public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
569 {
570 if (d())
571 {
572 lock (m_Cache)
573 {
574 // update the cached role
575 string cacheKey = "role-" + RoleID.ToString();
576 object obj;
577 if (m_Cache.TryGetValue(cacheKey, out obj))
578 {
579 GroupRolesData r = (GroupRolesData)obj;
580 r.Members++;
581 }
582  
583 // add this agent to the list of role members
584 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
585 if (m_Cache.TryGetValue(cacheKey, out obj))
586 {
587 try
588 {
589 // This may throw an exception, in which case the agentID is not a UUID but a full ID
590 // In that case, let's just remove the whoe things from the cache
591 UUID id = new UUID(AgentID);
592 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
593 List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
594 GroupRoleMembersData rm = new GroupRoleMembersData();
595 rm.MemberID = id;
596 rm.RoleID = RoleID;
597 rmlist.Add(rm);
598 }
599 catch
600 {
601 m_Cache.Remove(cacheKey);
602 }
603 }
604  
605 // Remove the cached info about this agent's roles
606 // because we don't have enough local info about the new role
607 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
608 if (m_Cache.Contains(cacheKey))
609 m_Cache.Remove(cacheKey);
610  
611 }
612 }
613 }
614  
615 public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
616 {
617 if (d())
618 {
619 lock (m_Cache)
620 {
621 // update the cached role
622 string cacheKey = "role-" + RoleID.ToString();
623 object obj;
624 if (m_Cache.TryGetValue(cacheKey, out obj))
625 {
626 GroupRolesData r = (GroupRolesData)obj;
627 r.Members--;
628 }
629  
630 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
631 if (m_Cache.Contains(cacheKey))
632 m_Cache.Remove(cacheKey);
633  
634 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
635 if (m_Cache.Contains(cacheKey))
636 m_Cache.Remove(cacheKey);
637 }
638 }
639 }
640  
641 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
642 {
643 object roles = null;
644 bool firstCall = false;
645 string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
646  
647 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
648  
649 while (true)
650 {
651 lock (m_Cache)
652 {
653 if (m_Cache.TryGetValue(cacheKey, out roles))
654 {
655 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
656 return (List<GroupRolesData>)roles;
657 }
658  
659 // not cached
660 if (!m_ActiveRequests.ContainsKey(cacheKey))
661 {
662 m_ActiveRequests.Add(cacheKey, true);
663 firstCall = true;
664 }
665 }
666  
667 if (firstCall)
668 {
669 roles = d();
670 lock (m_Cache)
671 {
672 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
673 m_ActiveRequests.Remove(cacheKey);
674 return (List<GroupRolesData>)roles;
675 }
676 }
677 else
678 Thread.Sleep(50);
679 }
680 }
681  
682 public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
683 {
684 d();
685  
686 lock (m_Cache)
687 {
688 // Invalidate cached info, because it has ActiveRoleID and Powers
689 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
690 if (m_Cache.Contains(cacheKey))
691 m_Cache.Remove(cacheKey);
692  
693 cacheKey = "memberships-" + AgentID.ToString();
694 if (m_Cache.Contains(cacheKey))
695 m_Cache.Remove(cacheKey);
696 }
697 }
698  
699 public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
700 {
701 d();
702  
703 lock (m_Cache)
704 {
705 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
706 if (m_Cache.Contains(cacheKey))
707 m_Cache.Remove(cacheKey);
708  
709 cacheKey = "memberships-" + AgentID.ToString();
710 if (m_Cache.Contains(cacheKey))
711 m_Cache.Remove(cacheKey);
712  
713 cacheKey = "active-" + AgentID.ToString();
714 object m = null;
715 if (m_Cache.TryGetValue(cacheKey, out m))
716 {
717 GroupMembershipData membership = (GroupMembershipData)m;
718 membership.ListInProfile = ListInProfile;
719 membership.AcceptNotices = AcceptNotices;
720 }
721 }
722 }
723  
724 public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
725 {
726 if (d())
727 {
728 lock (m_Cache)
729 {
730 m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
731 string cacheKey = "notices-" + groupID.ToString();
732 if (m_Cache.Contains(cacheKey))
733 m_Cache.Remove(cacheKey);
734  
735 }
736  
737 return true;
738 }
739  
740 return false;
741 }
742  
743 public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
744 {
745 object notice = null;
746 bool firstCall = false;
747 string cacheKey = "notice-" + noticeID.ToString();
748  
749 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
750  
751 while (true)
752 {
753 lock (m_Cache)
754 {
755 if (m_Cache.TryGetValue(cacheKey, out notice))
756 {
757 return (GroupNoticeInfo)notice;
758 }
759  
760 // not cached
761 if (!m_ActiveRequests.ContainsKey(cacheKey))
762 {
763 m_ActiveRequests.Add(cacheKey, true);
764 firstCall = true;
765 }
766 }
767  
768 if (firstCall)
769 {
770 GroupNoticeInfo _notice = d();
771  
772 lock (m_Cache)
773 {
774 m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
775 m_ActiveRequests.Remove(cacheKey);
776 return _notice;
777 }
778 }
779 else
780 Thread.Sleep(50);
781 }
782 }
783  
784 public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
785 {
786 object notices = null;
787 bool firstCall = false;
788 string cacheKey = "notices-" + GroupID.ToString();
789  
790 //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
791  
792 while (true)
793 {
794 lock (m_Cache)
795 {
796 if (m_Cache.TryGetValue(cacheKey, out notices))
797 {
798 //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
799 return (List<ExtendedGroupNoticeData>)notices;
800 }
801  
802 // not cached
803 if (!m_ActiveRequests.ContainsKey(cacheKey))
804 {
805 m_ActiveRequests.Add(cacheKey, true);
806 firstCall = true;
807 }
808 }
809  
810 if (firstCall)
811 {
812 notices = d();
813  
814 lock (m_Cache)
815 {
816 m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
817 m_ActiveRequests.Remove(cacheKey);
818 return (List<ExtendedGroupNoticeData>)notices;
819 }
820 }
821 else
822 Thread.Sleep(50);
823 }
824 }
825  
826  
827 }
828 }