aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs88
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs33
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs4
4 files changed, 114 insertions, 15 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
index 10b83e6..2802e2f 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
30using System.Reflection; 31using System.Reflection;
31using log4net; 32using log4net;
32using Mono.Addins; 33using Mono.Addins;
@@ -36,15 +37,18 @@ using OpenMetaverse.StructuredData;
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
39 42
40namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 43namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
41{ 44{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsMessagingModule")]
43 public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule 46 public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule
44 { 47 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 49
47 private List<Scene> m_sceneList = new List<Scene>(); 50 private List<Scene> m_sceneList = new List<Scene>();
51 private IPresenceService m_presenceService;
48 52
49 private IMessageTransferModule m_msgTransferModule = null; 53 private IMessageTransferModule m_msgTransferModule = null;
50 54
@@ -54,7 +58,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
54 private bool m_groupMessagingEnabled = false; 58 private bool m_groupMessagingEnabled = false;
55 private bool m_debugEnabled = true; 59 private bool m_debugEnabled = true;
56 60
57 #region IRegionModuleBase Members 61 /// <summary>
62 /// If enabled, module only tries to send group IMs to online users by querying cached presence information.
63 /// </summary>
64 private bool m_messageOnlineAgentsOnly;
65
66 /// <summary>
67 /// Cache for online users.
68 /// </summary>
69 /// <remarks>
70 /// Group ID is key, presence information for online members is value.
71 /// Will only be non-null if m_messageOnlineAgentsOnly = true
72 /// We cache here so that group messages don't constantly have to re-request the online user list to avoid
73 /// attempted expensive sending of messages to offline users.
74 /// The tradeoff is that a user that comes online will not receive messages consistently from all other users
75 /// until caches have updated.
76 /// Therefore, we set the cache expiry to just 20 seconds.
77 /// </remarks>
78 private ExpiringCache<UUID, PresenceInfo[]> m_usersOnlineCache;
79
80 private int m_usersOnlineCacheExpirySeconds = 20;
81
82 #region Region Module interfaceBase Members
58 83
59 public void Initialise(IConfigSource config) 84 public void Initialise(IConfigSource config)
60 { 85 {
@@ -83,10 +108,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
83 return; 108 return;
84 } 109 }
85 110
111 m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
112
113 if (m_messageOnlineAgentsOnly)
114 m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
115
86 m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); 116 m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
87 } 117 }
88 118
89 m_log.Info("[GROUPS-MESSAGING]: GroupsMessagingModule starting up"); 119 m_log.InfoFormat(
120 "[GROUPS-MESSAGING]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
121 m_messageOnlineAgentsOnly, m_debugEnabled);
90 } 122 }
91 123
92 public void AddRegion(Scene scene) 124 public void AddRegion(Scene scene)
@@ -126,6 +158,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
126 return; 158 return;
127 } 159 }
128 160
161 if (m_presenceService == null)
162 m_presenceService = scene.PresenceService;
129 163
130 m_sceneList.Add(scene); 164 m_sceneList.Add(scene);
131 165
@@ -207,12 +241,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
207 public void SendMessageToGroup(GridInstantMessage im, UUID groupID) 241 public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
208 { 242 {
209 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); 243 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID);
210 244 int groupMembersCount = groupMembers.Count;
211 if (m_debugEnabled) 245
212 m_log.DebugFormat( 246 if (m_messageOnlineAgentsOnly)
213 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", 247 {
214 groupID, groupMembers.Count); 248 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
215 249
250 // We cache in order not to overwhlem the presence service on large grids with many groups. This does
251 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
252 // (assuming this is the same across all grid simulators).
253 PresenceInfo[] onlineAgents;
254 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
255 {
256 onlineAgents = m_presenceService.GetAgents(t1);
257 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
258 }
259
260 HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
261 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
262
263 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
264
265 // if (m_debugEnabled)
266// m_log.DebugFormat(
267// "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
268// groupID, groupMembersCount, groupMembers.Count());
269 }
270 else
271 {
272 if (m_debugEnabled)
273 m_log.DebugFormat(
274 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
275 groupID, groupMembers.Count);
276 }
277
278 int requestStartTick = Environment.TickCount;
279
216 foreach (GroupMembersData member in groupMembers) 280 foreach (GroupMembersData member in groupMembers)
217 { 281 {
218 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) 282 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
@@ -254,6 +318,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
254 ProcessMessageFromGroupSession(msg); 318 ProcessMessageFromGroupSession(msg);
255 } 319 }
256 } 320 }
321
322 // Temporary for assessing how long it still takes to send messages to large online groups.
323 if (m_messageOnlineAgentsOnly)
324 m_log.DebugFormat(
325 "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
326 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
257 } 327 }
258 328
259 #region SimGridEventHandlers 329 #region SimGridEventHandlers
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 65bd26c..ae0ad02 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -43,7 +43,7 @@ using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
43 43
44namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 44namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
45{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
47 public class GroupsModule : ISharedRegionModule, IGroupsModule 47 public class GroupsModule : ISharedRegionModule, IGroupsModule
48 { 48 {
49 /// <summary> 49 /// <summary>
@@ -86,7 +86,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
86 private bool m_debugEnabled = false; 86 private bool m_debugEnabled = false;
87 private int m_levelGroupCreate = 0; 87 private int m_levelGroupCreate = 0;
88 88
89 #region IRegionModuleBase Members 89 #region Region Module interfaceBase Members
90 90
91 public void Initialise(IConfigSource config) 91 public void Initialise(IConfigSource config)
92 { 92 {
@@ -123,7 +123,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
123 public void AddRegion(Scene scene) 123 public void AddRegion(Scene scene)
124 { 124 {
125 if (m_groupsEnabled) 125 if (m_groupsEnabled)
126 {
126 scene.RegisterModuleInterface<IGroupsModule>(this); 127 scene.RegisterModuleInterface<IGroupsModule>(this);
128 scene.AddCommand(
129 "debug",
130 this,
131 "debug groups verbose",
132 "debug groups verbose <true|false>",
133 "This setting turns on very verbose groups debugging",
134 HandleDebugGroupsVerbose);
135 }
136 }
137
138 private void HandleDebugGroupsVerbose(object modules, string[] args)
139 {
140 if (args.Length < 4)
141 {
142 MainConsole.Instance.Output("Usage: debug groups verbose <true|false>");
143 return;
144 }
145
146 bool verbose = false;
147 if (!bool.TryParse(args[3], out verbose))
148 {
149 MainConsole.Instance.Output("Usage: debug groups verbose <true|false>");
150 return;
151 }
152
153 m_debugEnabled = verbose;
154
155 MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
127 } 156 }
128 157
129 public void RegionLoaded(Scene scene) 158 public void RegionLoaded(Scene scene)
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 5d57f70..7bae8f7 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -102,7 +102,7 @@ using OpenSim.Services.Interfaces;
102 102
103namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 103namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
104{ 104{
105 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 105 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianGroupsServicesConnectorModule")]
106 public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector 106 public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector
107 { 107 {
108 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 108 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
176 // private IUserAccountService m_accountService = null; 176 // private IUserAccountService m_accountService = null;
177 177
178 178
179 #region IRegionModuleBase Members 179 #region Region Module interfaceBase Members
180 180
181 public string Name 181 public string Name
182 { 182 {
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index d412cd1..d0c3ea5 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -47,7 +47,7 @@ using OpenSim.Services.Interfaces;
47 47
48namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 48namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
49{ 49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XmlRpcGroupsServicesConnectorModule")]
51 public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector 51 public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector
52 { 52 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -83,7 +83,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
83 private Dictionary<UUID, List<UUID>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<UUID>>(); 83 private Dictionary<UUID, List<UUID>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<UUID>>();
84 private Dictionary<UUID, List<UUID>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<UUID>>(); 84 private Dictionary<UUID, List<UUID>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<UUID>>();
85 85
86 #region IRegionModuleBase Members 86 #region Region Module interfaceBase Members
87 87
88 public string Name 88 public string Name
89 { 89 {