OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
RemoteConnectorCacheWrapper.cs
Go to the documentation of this file.
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 using OpenSim.Services.Interfaces;
36 
37 using OpenMetaverse;
38 
39 namespace OpenSim.Groups
40 {
41  public delegate ExtendedGroupRecord GroupRecordDelegate();
43  public delegate List<GroupMembershipData> GroupMembershipListDelegate();
44  public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate();
45  public delegate List<GroupRolesData> GroupRolesListDelegate();
46  public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate();
47  public delegate GroupNoticeInfo NoticeDelegate();
48  public delegate List<ExtendedGroupNoticeData> NoticeListDelegate();
49  public delegate void VoidDelegate();
50  public delegate bool BooleanDelegate();
51 
53  {
54  private ForeignImporter m_ForeignImporter;
55 
56  private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
57  private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
58 
59  // This all important cache cahces objects of different types:
60  // group-<GroupID> or group-<Name> => ExtendedGroupRecord
61  // active-<AgentID> => GroupMembershipData
62  // membership-<AgentID>-<GroupID> => GroupMembershipData
63  // memberships-<AgentID> => List<GroupMembershipData>
64  // members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData>
65  // role-<RoleID> => GroupRolesData
66  // roles-<GroupID> => List<GroupRolesData> ; all roles in the group
67  // roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has
68  // rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData>
69  // notice-<noticeID> => GroupNoticeInfo
70  // notices-<GroupID> => List<ExtendedGroupNoticeData>
71  private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>();
72 
74  {
75  m_ForeignImporter = new ForeignImporter(uman);
76  }
77 
78  public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
79  {
80  //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
81  //reason = string.Empty;
82 
83  //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
84  // membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
85  ExtendedGroupRecord group = d();
86 
87  if (group == null)
88  return UUID.Zero;
89 
90  if (group.GroupID != UUID.Zero)
91  lock (m_Cache)
92  {
93  m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
94  if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
95  m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
96  }
97 
98  return group.GroupID;
99  }
100 
101  public bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
102  {
103  //reason = string.Empty;
104  //ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
105  ExtendedGroupRecord group = d();
106 
107  if (group != null && group.GroupID != UUID.Zero)
108  lock (m_Cache)
109  m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
110  return true;
111  }
112 
113  public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
114  {
115  //if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
116  // return null;
117 
118  object group = null;
119  bool firstCall = false;
120  string cacheKey = "group-";
121  if (GroupID != UUID.Zero)
122  cacheKey += GroupID.ToString();
123  else
124  cacheKey += GroupName;
125 
126  //m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey);
127 
128  while (true)
129  {
130  lock (m_Cache)
131  {
132  if (m_Cache.TryGetValue(cacheKey, out group))
133  {
134  //m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey);
135  return (ExtendedGroupRecord)group;
136  }
137 
138  // not cached
139  if (!m_ActiveRequests.ContainsKey(cacheKey))
140  {
141  m_ActiveRequests.Add(cacheKey, true);
142  firstCall = true;
143  }
144  }
145 
146  if (firstCall)
147  {
148  try
149  {
150  //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
151  group = d();
152 
153  lock (m_Cache)
154  {
155  m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
156  return (ExtendedGroupRecord)group;
157  }
158  }
159  finally
160  {
161  m_ActiveRequests.Remove(cacheKey);
162  }
163  }
164  else
165  Thread.Sleep(50);
166  }
167  }
168 
169  public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
170  {
171  GroupMembershipData membership = d();
172  if (membership == null)
173  return false;
174 
175  lock (m_Cache)
176  {
177  // first, remove everything! add a user is a heavy-duty op
178  m_Cache.Clear();
179 
180  m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
181  m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
182  }
183 
184 
185  return true;
186  }
187 
188  public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
189  {
190  d();
191 
192  lock (m_Cache)
193  {
194  string cacheKey = "active-" + AgentID.ToString();
195  if (m_Cache.Contains(cacheKey))
196  m_Cache.Remove(cacheKey);
197 
198  cacheKey = "memberships-" + AgentID.ToString();
199  if (m_Cache.Contains(cacheKey))
200  m_Cache.Remove(cacheKey);
201 
202  cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
203  if (m_Cache.Contains(cacheKey))
204  m_Cache.Remove(cacheKey);
205 
206  cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
207  if (m_Cache.Contains(cacheKey))
208  m_Cache.Remove(cacheKey);
209 
210  cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString();
211  if (m_Cache.Contains(cacheKey))
212  m_Cache.Remove(cacheKey);
213  }
214  }
215 
216  public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
217  {
218  GroupMembershipData activeGroup = d();
219  string cacheKey = "active-" + AgentID.ToString();
220  lock (m_Cache)
221  if (m_Cache.Contains(cacheKey))
222  m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
223  }
224 
226  {
227  object membership = null;
228  bool firstCall = false;
229  string cacheKey = "active-" + AgentID.ToString();
230 
231  //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
232 
233  while (true)
234  {
235  lock (m_Cache)
236  {
237  if (m_Cache.TryGetValue(cacheKey, out membership))
238  {
239  //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
240  return (ExtendedGroupMembershipData)membership;
241  }
242 
243  // not cached
244  if (!m_ActiveRequests.ContainsKey(cacheKey))
245  {
246  m_ActiveRequests.Add(cacheKey, true);
247  firstCall = true;
248  }
249  }
250 
251  if (firstCall)
252  {
253  try
254  {
255  membership = d();
256 
257  lock (m_Cache)
258  {
259  m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
260  return (ExtendedGroupMembershipData)membership;
261  }
262  }
263  finally
264  {
265  m_ActiveRequests.Remove(cacheKey);
266  }
267  }
268  else
269  Thread.Sleep(50);
270  }
271 
272  }
273 
275  {
276  object membership = null;
277  bool firstCall = false;
278  string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
279 
280  //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
281 
282  while (true)
283  {
284  lock (m_Cache)
285  {
286  if (m_Cache.TryGetValue(cacheKey, out membership))
287  {
288  //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
289  return (ExtendedGroupMembershipData)membership;
290  }
291 
292  // not cached
293  if (!m_ActiveRequests.ContainsKey(cacheKey))
294  {
295  m_ActiveRequests.Add(cacheKey, true);
296  firstCall = true;
297  }
298  }
299 
300  if (firstCall)
301  {
302  try
303  {
304  membership = d();
305  lock (m_Cache)
306  {
307  m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
308  return (ExtendedGroupMembershipData)membership;
309  }
310  }
311  finally
312  {
313  m_ActiveRequests.Remove(cacheKey);
314  }
315  }
316  else
317  Thread.Sleep(50);
318  }
319  }
320 
321  public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
322  {
323  object memberships = null;
324  bool firstCall = false;
325  string cacheKey = "memberships-" + AgentID.ToString();
326 
327  //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
328 
329  while (true)
330  {
331  lock (m_Cache)
332  {
333  if (m_Cache.TryGetValue(cacheKey, out memberships))
334  {
335  //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
336  return (List<GroupMembershipData>)memberships;
337  }
338 
339  // not cached
340  if (!m_ActiveRequests.ContainsKey(cacheKey))
341  {
342  m_ActiveRequests.Add(cacheKey, true);
343  firstCall = true;
344  }
345  }
346 
347  if (firstCall)
348  {
349  try
350  {
351  memberships = d();
352  lock (m_Cache)
353  {
354  m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
355  return (List<GroupMembershipData>)memberships;
356  }
357  }
358  finally
359  {
360  m_ActiveRequests.Remove(cacheKey);
361  }
362  }
363  else
364  Thread.Sleep(50);
365  }
366  }
367 
368  public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
369  {
370  object members = null;
371  bool firstCall = false;
372  // we need to key in also on the requester, because different ppl have different view privileges
373  string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
374 
375  //m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
376 
377  while (true)
378  {
379  lock (m_Cache)
380  {
381  if (m_Cache.TryGetValue(cacheKey, out members))
382  {
383  List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
384  return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
385  }
386 
387  // not cached
388  if (!m_ActiveRequests.ContainsKey(cacheKey))
389  {
390  m_ActiveRequests.Add(cacheKey, true);
391  firstCall = true;
392  }
393  }
394 
395  if (firstCall)
396  {
397  try
398  {
399  List<ExtendedGroupMembersData> _members = d();
400 
401  if (_members != null && _members.Count > 0)
402  members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
403  else
404  members = new List<GroupMembersData>();
405 
406  lock (m_Cache)
407  {
408  //m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
409  m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
410 
411  return (List<GroupMembersData>)members;
412  }
413  }
414  finally
415  {
416  m_ActiveRequests.Remove(cacheKey);
417  }
418  }
419  else
420  Thread.Sleep(50);
421  }
422  }
423 
424  public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
425  {
426  if (d())
427  {
428  GroupRolesData role = new GroupRolesData();
429  role.Description = description;
430  role.Members = 0;
431  role.Name = name;
432  role.Powers = powers;
433  role.RoleID = roleID;
434  role.Title = title;
435 
436  lock (m_Cache)
437  {
438  m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
439 
440  // also remove this list
441  if (m_Cache.Contains("roles-" + groupID.ToString()))
442  m_Cache.Remove("roles-" + groupID.ToString());
443 
444  }
445 
446  return true;
447  }
448 
449  return false;
450  }
451 
452  public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
453  {
454  if (d())
455  {
456  object role;
457  lock (m_Cache)
458  if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
459  {
460  GroupRolesData r = (GroupRolesData)role;
461  r.Description = description;
462  r.Name = name;
463  r.Powers = powers;
464  r.Title = title;
465 
466  m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
467  }
468  return true;
469  }
470  else
471  {
472  lock (m_Cache)
473  {
474  if (m_Cache.Contains("role-" + roleID.ToString()))
475  m_Cache.Remove("role-" + roleID.ToString());
476 
477  // also remove these lists, because they will have an outdated role
478  if (m_Cache.Contains("roles-" + groupID.ToString()))
479  m_Cache.Remove("roles-" + groupID.ToString());
480 
481  }
482 
483  return false;
484  }
485  }
486 
487  public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
488  {
489  d();
490 
491  lock (m_Cache)
492  {
493  if (m_Cache.Contains("role-" + roleID.ToString()))
494  m_Cache.Remove("role-" + roleID.ToString());
495 
496  // also remove the list, because it will have an removed role
497  if (m_Cache.Contains("roles-" + groupID.ToString()))
498  m_Cache.Remove("roles-" + groupID.ToString());
499 
500  if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
501  m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
502 
503  if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
504  m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
505  }
506  }
507 
508  public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
509  {
510  object roles = null;
511  bool firstCall = false;
512  string cacheKey = "roles-" + GroupID.ToString();
513 
514  while (true)
515  {
516  lock (m_Cache)
517  {
518  if (m_Cache.TryGetValue(cacheKey, out roles))
519  return (List<GroupRolesData>)roles;
520 
521  // not cached
522  if (!m_ActiveRequests.ContainsKey(cacheKey))
523  {
524  m_ActiveRequests.Add(cacheKey, true);
525  firstCall = true;
526  }
527  }
528 
529  if (firstCall)
530  {
531  try
532  {
533  roles = d();
534  if (roles != null)
535  {
536  lock (m_Cache)
537  {
538  m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
539  return (List<GroupRolesData>)roles;
540  }
541  }
542  }
543  finally
544  {
545  m_ActiveRequests.Remove(cacheKey);
546  }
547  }
548  else
549  Thread.Sleep(50);
550  }
551  }
552 
553  public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
554  {
555  object rmembers = null;
556  bool firstCall = false;
557  // we need to key in also on the requester, because different ppl have different view privileges
558  string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
559 
560  //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
561  while (true)
562  {
563  lock (m_Cache)
564  {
565  if (m_Cache.TryGetValue(cacheKey, out rmembers))
566  {
567  List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
568  return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
569  }
570 
571  // not cached
572  if (!m_ActiveRequests.ContainsKey(cacheKey))
573  {
574  m_ActiveRequests.Add(cacheKey, true);
575  firstCall = true;
576  }
577  }
578 
579  if (firstCall)
580  {
581  try
582  {
583  List<ExtendedGroupRoleMembersData> _rmembers = d();
584 
585  if (_rmembers != null && _rmembers.Count > 0)
586  rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
587  else
588  rmembers = new List<GroupRoleMembersData>();
589 
590  lock (m_Cache)
591  {
592  // For some strange reason, when I cache the list of GroupRoleMembersData,
593  // it gets emptied out. The TryGet gets an empty list...
594  //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
595  // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
596  // I don't get it.
597  m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
598  return (List<GroupRoleMembersData>)rmembers;
599  }
600  }
601  finally
602  {
603  m_ActiveRequests.Remove(cacheKey);
604  }
605  }
606  else
607  Thread.Sleep(50);
608  }
609  }
610 
611  public void AddAgentToGroupRole(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  {
623  r.Members++;
624  }
625 
626  // add this agent to the list of role members
627  cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
628  if (m_Cache.TryGetValue(cacheKey, out obj))
629  {
630  try
631  {
632  // This may throw an exception, in which case the agentID is not a UUID but a full ID
633  // In that case, let's just remove the whoe things from the cache
634  UUID id = new UUID(AgentID);
635  List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
636  List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
638  rm.MemberID = id;
639  rm.RoleID = RoleID;
640  rmlist.Add(rm);
641  }
642  catch
643  {
644  m_Cache.Remove(cacheKey);
645  }
646  }
647 
648  // Remove the cached info about this agent's roles
649  // because we don't have enough local info about the new role
650  cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
651  if (m_Cache.Contains(cacheKey))
652  m_Cache.Remove(cacheKey);
653 
654  }
655  }
656  }
657 
658  public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
659  {
660  if (d())
661  {
662  lock (m_Cache)
663  {
664  // update the cached role
665  string cacheKey = "role-" + RoleID.ToString();
666  object obj;
667  if (m_Cache.TryGetValue(cacheKey, out obj))
668  {
670  r.Members--;
671  }
672 
673  cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
674  if (m_Cache.Contains(cacheKey))
675  m_Cache.Remove(cacheKey);
676 
677  cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
678  if (m_Cache.Contains(cacheKey))
679  m_Cache.Remove(cacheKey);
680  }
681  }
682  }
683 
684  public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
685  {
686  object roles = null;
687  bool firstCall = false;
688  string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
689 
690  //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
691 
692  while (true)
693  {
694  lock (m_Cache)
695  {
696  if (m_Cache.TryGetValue(cacheKey, out roles))
697  {
698  //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
699  return (List<GroupRolesData>)roles;
700  }
701 
702  // not cached
703  if (!m_ActiveRequests.ContainsKey(cacheKey))
704  {
705  m_ActiveRequests.Add(cacheKey, true);
706  firstCall = true;
707  }
708  }
709 
710  if (firstCall)
711  {
712  try
713  {
714  roles = d();
715  lock (m_Cache)
716  {
717  m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
718  m_ActiveRequests.Remove(cacheKey);
719  return (List<GroupRolesData>)roles;
720  }
721  }
722  finally
723  {
724  m_ActiveRequests.Remove(cacheKey);
725  }
726  }
727  else
728  Thread.Sleep(50);
729  }
730  }
731 
732  public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
733  {
734  d();
735 
736  lock (m_Cache)
737  {
738  // Invalidate cached info, because it has ActiveRoleID and Powers
739  string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
740  if (m_Cache.Contains(cacheKey))
741  m_Cache.Remove(cacheKey);
742 
743  cacheKey = "memberships-" + AgentID.ToString();
744  if (m_Cache.Contains(cacheKey))
745  m_Cache.Remove(cacheKey);
746  }
747  }
748 
749  public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
750  {
751  d();
752 
753  lock (m_Cache)
754  {
755  string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
756  if (m_Cache.Contains(cacheKey))
757  m_Cache.Remove(cacheKey);
758 
759  cacheKey = "memberships-" + AgentID.ToString();
760  if (m_Cache.Contains(cacheKey))
761  m_Cache.Remove(cacheKey);
762 
763  cacheKey = "active-" + AgentID.ToString();
764  object m = null;
765  if (m_Cache.TryGetValue(cacheKey, out m))
766  {
768  membership.ListInProfile = ListInProfile;
769  membership.AcceptNotices = AcceptNotices;
770  }
771  }
772  }
773 
774  public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
775  {
776  if (d())
777  {
778  lock (m_Cache)
779  {
780  m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
781  string cacheKey = "notices-" + groupID.ToString();
782  if (m_Cache.Contains(cacheKey))
783  m_Cache.Remove(cacheKey);
784 
785  }
786 
787  return true;
788  }
789 
790  return false;
791  }
792 
794  {
795  object notice = null;
796  bool firstCall = false;
797  string cacheKey = "notice-" + noticeID.ToString();
798 
799  //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
800 
801  while (true)
802  {
803  lock (m_Cache)
804  {
805  if (m_Cache.TryGetValue(cacheKey, out notice))
806  {
807  return (GroupNoticeInfo)notice;
808  }
809 
810  // not cached
811  if (!m_ActiveRequests.ContainsKey(cacheKey))
812  {
813  m_ActiveRequests.Add(cacheKey, true);
814  firstCall = true;
815  }
816  }
817 
818  if (firstCall)
819  {
820  try
821  {
822  GroupNoticeInfo _notice = d();
823 
824  lock (m_Cache)
825  {
826  m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
827  return _notice;
828  }
829  }
830  finally
831  {
832  m_ActiveRequests.Remove(cacheKey);
833  }
834  }
835  else
836  Thread.Sleep(50);
837  }
838  }
839 
840  public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
841  {
842  object notices = null;
843  bool firstCall = false;
844  string cacheKey = "notices-" + GroupID.ToString();
845 
846  //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
847 
848  while (true)
849  {
850  lock (m_Cache)
851  {
852  if (m_Cache.TryGetValue(cacheKey, out notices))
853  {
854  //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
855  return (List<ExtendedGroupNoticeData>)notices;
856  }
857 
858  // not cached
859  if (!m_ActiveRequests.ContainsKey(cacheKey))
860  {
861  m_ActiveRequests.Add(cacheKey, true);
862  firstCall = true;
863  }
864  }
865 
866  if (firstCall)
867  {
868  try
869  {
870  notices = d();
871 
872  lock (m_Cache)
873  {
874  m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
875  return (List<ExtendedGroupNoticeData>)notices;
876  }
877  }
878  finally
879  {
880  m_ActiveRequests.Remove(cacheKey);
881  }
882  }
883  else
884  Thread.Sleep(50);
885  }
886  }
887  }
888 }
bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
delegate GroupMembershipData GroupMembershipDelegate()
void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
delegate List< GroupRolesData > GroupRolesListDelegate()
List< GroupRolesData > GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
List< GroupMembershipData > GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
List< GroupRolesData > GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
delegate ExtendedGroupRecord GroupRecordDelegate()
void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
delegate void VoidDelegate()
bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
List< GroupMembersData > GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
delegate List< ExtendedGroupMembersData > GroupMembersListDelegate()
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
delegate List< ExtendedGroupNoticeData > NoticeListDelegate()
void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
List< GroupRoleMembersData > GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
List< ExtendedGroupNoticeData > GetGroupNotices(UUID GroupID, NoticeListDelegate d)
delegate bool BooleanDelegate()
GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
delegate List< ExtendedGroupRoleMembersData > RoleMembersListDelegate()
This maintains the relationship between a UUID and a user name.
delegate List< GroupMembershipData > GroupMembershipListDelegate()
delegate GroupNoticeInfo NoticeDelegate()
void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)