diff options
Diffstat (limited to 'OpenSim/Region/DataSnapshot/DataSnapshotManager.cs')
-rw-r--r-- | OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 451 |
1 files changed, 174 insertions, 277 deletions
diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index af3e547..6fdedb4 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | |||
@@ -37,49 +37,62 @@ using System.Xml; | |||
37 | using libsecondlife; | 37 | using libsecondlife; |
38 | using log4net; | 38 | using log4net; |
39 | using Nini.Config; | 39 | using Nini.Config; |
40 | using OpenSim.Framework; | ||
40 | using OpenSim.Framework.Communications; | 41 | using OpenSim.Framework.Communications; |
41 | using OpenSim.Region.DataSnapshot.Interfaces; | 42 | using OpenSim.Region.DataSnapshot.Interfaces; |
42 | using OpenSim.Region.Environment.Interfaces; | 43 | using OpenSim.Region.Environment.Interfaces; |
43 | using OpenSim.Region.Environment.Scenes; | 44 | using OpenSim.Region.Environment.Scenes; |
45 | using libsecondlife.Packets; | ||
44 | 46 | ||
45 | namespace OpenSim.Region.DataSnapshot | 47 | namespace OpenSim.Region.DataSnapshot |
46 | { | 48 | { |
47 | public class DataSnapshotManager : IRegionModule | 49 | public class DataSnapshotManager : IRegionModule, IDataSnapshot |
48 | { | 50 | { |
49 | #region Class members | 51 | #region Class members |
50 | private List<Scene> m_scenes = new List<Scene>(); | 52 | //Information from config |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | private bool m_enabled = false; | 53 | private bool m_enabled = false; |
53 | private bool m_configLoaded = false; | 54 | private bool m_configLoaded = false; |
54 | internal object m_syncInit = new object(); | 55 | private List<String> m_disabledModules = new List<String>(); |
55 | private DataRequestHandler m_requests = null; | ||
56 | private Dictionary<Scene, List<IDataSnapshotProvider>> m_dataproviders = new Dictionary<Scene, List<IDataSnapshotProvider>>(); | ||
57 | private Dictionary<string, string> m_gridinfo = new Dictionary<string, string>(); | 56 | private Dictionary<string, string> m_gridinfo = new Dictionary<string, string>(); |
58 | //private int m_oldestSnapshot = 0; | ||
59 | private int m_maxSnapshots = 500; | ||
60 | private int m_lastSnapshot = 0; | ||
61 | private string m_snapsDir = "DataSnapshot"; | 57 | private string m_snapsDir = "DataSnapshot"; |
58 | |||
59 | //Lists of stuff we need | ||
60 | private List<Scene> m_scenes = new List<Scene>(); | ||
61 | private List<IDataSnapshotProvider> m_dataproviders = new List<IDataSnapshotProvider>(); | ||
62 | |||
63 | //Various internal objects | ||
64 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
65 | internal object m_syncInit = new object(); | ||
66 | |||
67 | //DataServices and networking | ||
62 | private string m_dataServices = "noservices"; | 68 | private string m_dataServices = "noservices"; |
63 | private string m_listener_port = "9000"; //TODO: Set default port over 9000 | 69 | public string m_listener_port = "9000"; //TODO: Set default port over 9000 |
64 | private string m_hostname = "127.0.0.1"; | 70 | public string m_hostname = "127.0.0.1"; |
71 | |||
72 | //Update timers | ||
65 | private Timer m_periodic = null; | 73 | private Timer m_periodic = null; |
66 | private int m_period = 60; // in seconds | 74 | private int m_period = 20; // in seconds |
67 | private List<string> m_disabledModules = new List<string>(); | 75 | private int m_maxStales = 500; |
76 | private int m_stales = 0; | ||
77 | private Timer m_passedCheck = null; | ||
78 | private bool m_periodPassed = false; | ||
79 | |||
80 | //Program objects | ||
81 | private SnapshotStore m_snapStore = null; | ||
82 | private DataRequestHandler m_requests = null; | ||
83 | |||
68 | #endregion | 84 | #endregion |
69 | 85 | ||
70 | #region IRegionModule | 86 | #region IRegionModule |
87 | |||
71 | public void Close() | 88 | public void Close() |
72 | { | 89 | { |
73 | 90 | m_log.Info("[DATASNAPSHOT]: Close called"); | |
74 | } | 91 | } |
75 | 92 | ||
76 | public void Initialise(Scene scene, IConfigSource config) | 93 | public void Initialise(Scene scene, IConfigSource config) |
77 | { | 94 | { |
78 | if (!m_scenes.Contains(scene)) | 95 | if (!m_configLoaded) { |
79 | m_scenes.Add(scene); | ||
80 | |||
81 | if (!m_configLoaded) | ||
82 | { | ||
83 | m_configLoaded = true; | 96 | m_configLoaded = true; |
84 | m_log.Info("[DATASNAPSHOT]: Loading configuration"); | 97 | m_log.Info("[DATASNAPSHOT]: Loading configuration"); |
85 | //Read from the config for options | 98 | //Read from the config for options |
@@ -99,49 +112,59 @@ namespace OpenSim.Region.DataSnapshot | |||
99 | //Non gridmode stuff | 112 | //Non gridmode stuff |
100 | } | 113 | } |
101 | 114 | ||
102 | m_gridinfo.Add("Name", config.Configs["DataSnapshot"].GetString("gridname", "harbl")); | 115 | m_gridinfo.Add("Name", config.Configs["DataSnapshot"].GetString("gridname", "harbl")); |
103 | m_maxSnapshots = config.Configs["DataSnapshot"].GetInt("max_snapshots", m_maxSnapshots); | 116 | m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); |
104 | m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); | 117 | m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); |
105 | m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); | 118 | m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); |
106 | m_dataServices = config.Configs["DataSnapshot"].GetString("data_services", m_dataServices); | 119 | m_dataServices = config.Configs["DataSnapshot"].GetString("data_services", m_dataServices); |
107 | m_listener_port = config.Configs["Network"].GetString("http_listener_port", m_listener_port); | 120 | m_listener_port = config.Configs["Network"].GetString("http_listener_port", m_listener_port); |
108 | //BUG: Naming a search data module "DESUDESUDESU" will cause it to not get loaded by default. | 121 | |
109 | //RESOLUTION: Wontfix, there are no Suiseiseki-loving developers | 122 | String[] annoying_string_array = config.Configs["DataSnapshot"].GetString("disable_modules", "").Split(".".ToCharArray()); |
110 | String[] annoying_string_array = config.Configs["DataSnapshot"].GetString("disable_modules", "DESUDESUDESU").Split(".".ToCharArray()); | 123 | foreach (String bloody_wanker in annoying_string_array) { |
111 | foreach (String bloody_wanker in annoying_string_array) | 124 | m_disabledModules.Add(bloody_wanker); |
112 | { | 125 | } |
113 | m_disabledModules.Add(bloody_wanker); | 126 | } catch (Exception) { |
114 | } | ||
115 | } | ||
116 | catch (Exception) | ||
117 | { | ||
118 | m_log.Info("[DATASNAPSHOT]: Could not load configuration. DataSnapshot will be disabled."); | 127 | m_log.Info("[DATASNAPSHOT]: Could not load configuration. DataSnapshot will be disabled."); |
119 | m_enabled = false; | 128 | m_enabled = false; |
120 | return; | 129 | return; |
121 | } | 130 | } |
122 | } | 131 | } |
123 | } | 132 | |
124 | if (Directory.Exists(m_snapsDir)) | 133 | m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); |
125 | { | ||
126 | m_log.Info("[DATASNAPSHOT] DataSnapshot directory already exists."); | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | // Try to create the directory. | ||
131 | m_log.Info("[DATASNAPSHOT] Creating " + m_snapsDir + " directory."); | ||
132 | try | ||
133 | { | ||
134 | Directory.CreateDirectory(m_snapsDir); | ||
135 | } | ||
136 | catch (Exception) | ||
137 | { | ||
138 | m_log.Error("[DATASNAPSHOT] Failed to create " + m_snapsDir + " directory."); | ||
139 | } | ||
140 | } | 134 | } |
141 | 135 | ||
142 | if (m_enabled) | 136 | if (m_enabled) |
143 | { | 137 | { |
144 | m_log.Info("[DATASNAPSHOT]: Scene added to module."); | 138 | m_log.Info("[DATASNAPSHOT]: Scene added to module."); |
139 | |||
140 | m_snapStore.AddScene(scene); | ||
141 | m_scenes.Add(scene); | ||
142 | |||
143 | Assembly currentasm = Assembly.GetExecutingAssembly(); | ||
144 | |||
145 | foreach (Type pluginType in currentasm.GetTypes()) | ||
146 | { | ||
147 | if (pluginType.IsPublic) | ||
148 | { | ||
149 | if (!pluginType.IsAbstract) | ||
150 | { | ||
151 | if (pluginType.GetInterface("IDataSnapshotProvider") != null) | ||
152 | { | ||
153 | IDataSnapshotProvider module = (IDataSnapshotProvider)Activator.CreateInstance(pluginType); | ||
154 | module.Initialize(scene, this); | ||
155 | module.OnStale += MarkDataStale; | ||
156 | |||
157 | m_dataproviders.Add(module); | ||
158 | m_snapStore.AddProvider(module); | ||
159 | |||
160 | m_log.Info("[DATASNAPSHOT]: Added new data provider type: " + pluginType.Name); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | //scene.OnRestart += OnSimRestart; | ||
167 | scene.EventManager.OnShutdown += delegate() { OnSimRestart(scene.RegionInfo); }; | ||
145 | } | 168 | } |
146 | else | 169 | else |
147 | { | 170 | { |
@@ -163,68 +186,35 @@ namespace OpenSim.Region.DataSnapshot | |||
163 | { | 186 | { |
164 | if (m_enabled) | 187 | if (m_enabled) |
165 | { | 188 | { |
166 | //Right now, only load ISearchData objects in the current assembly. | ||
167 | //Eventually allow it to load ISearchData objects from all assemblies. | ||
168 | Assembly currentasm = Assembly.GetExecutingAssembly(); | ||
169 | |||
170 | //Stolen from ModuleLoader.cs | ||
171 | foreach (Type pluginType in currentasm.GetTypes()) | ||
172 | { | ||
173 | if (pluginType.IsPublic) | ||
174 | { | ||
175 | if (!pluginType.IsAbstract) | ||
176 | { | ||
177 | if (pluginType.GetInterface("IDataSnapshotProvider") != null) | ||
178 | { | ||
179 | foreach (Scene scene in m_scenes) | ||
180 | { | ||
181 | IDataSnapshotProvider module = (IDataSnapshotProvider)Activator.CreateInstance(pluginType); | ||
182 | module.Initialize(scene, this); | ||
183 | //module.PrepareData(); | ||
184 | List<IDataSnapshotProvider> providerlist = null; | ||
185 | m_dataproviders.TryGetValue(scene, out providerlist); | ||
186 | if (providerlist == null) | ||
187 | { | ||
188 | providerlist = new List<IDataSnapshotProvider>(); | ||
189 | m_dataproviders.Add(scene, providerlist); | ||
190 | } | ||
191 | providerlist.Add(module); | ||
192 | |||
193 | } | ||
194 | m_log.Info("[DATASNAPSHOT]: Added new data provider type: " + pluginType.Name); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer | 189 | //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer |
201 | m_requests = new DataRequestHandler(m_scenes[0], this); | 190 | m_requests = new DataRequestHandler(m_scenes[0], this); |
202 | 191 | ||
203 | //Create timer | 192 | //Create update timer |
204 | m_periodic = new Timer(); | 193 | m_periodic = new Timer(); |
205 | m_periodic.Interval = m_period * 1000; | 194 | m_periodic.Interval = m_period * 1000; |
206 | m_periodic.Elapsed += SnapshotTimerCallback; | 195 | m_periodic.Elapsed += SnapshotTimerCallback; |
207 | m_periodic.Enabled = true; | 196 | |
197 | //Create update eligibility timer | ||
198 | m_passedCheck = new Timer(); | ||
199 | m_passedCheck.Interval = m_period * 1000; | ||
200 | m_passedCheck.Elapsed += UpdateEligibilityCallback; | ||
201 | m_passedCheck.Start(); | ||
208 | 202 | ||
209 | m_hostname = m_scenes[0].RegionInfo.ExternalHostName; | 203 | m_hostname = m_scenes[0].RegionInfo.ExternalHostName; |
210 | 204 | ||
211 | MakeNewSnapshot(); //Make the initial snapshot | 205 | //m_snapStore = new SnapshotStore(m_snapsDir, m_dataproviders, m_gridinfo, m_listener_port, m_hostname); |
206 | MakeEverythingStale(); | ||
212 | 207 | ||
213 | if (m_dataServices != "noservices") | 208 | if (m_dataServices != "noservices") |
214 | NotifyDataServices(m_dataServices); | 209 | NotifyDataServices(m_dataServices); |
215 | } | 210 | } |
216 | } | 211 | } |
212 | |||
217 | #endregion | 213 | #endregion |
218 | 214 | ||
219 | #region Associated helper functions | 215 | #region Associated helper functions |
220 | 216 | ||
221 | string DataFileName(Scene scene) | 217 | public Scene SceneForName(string name) |
222 | { | ||
223 | return Path.Combine(m_snapsDir, Path.ChangeExtension(scene.RegionInfo.RegionName, "xml")); | ||
224 | //return (m_snapsDir + Path.DirectorySeparatorChar + scene.RegionInfo.RegionName + ".xml"); | ||
225 | } | ||
226 | |||
227 | Scene SceneForName(string name) | ||
228 | { | 218 | { |
229 | foreach (Scene scene in m_scenes) | 219 | foreach (Scene scene in m_scenes) |
230 | if (scene.RegionInfo.RegionName == name) | 220 | if (scene.RegionInfo.RegionName == name) |
@@ -233,168 +223,19 @@ namespace OpenSim.Region.DataSnapshot | |||
233 | return null; | 223 | return null; |
234 | } | 224 | } |
235 | 225 | ||
236 | #endregion | 226 | public Scene SceneForUUID(LLUUID id) |
237 | |||
238 | #region [Private] XML snapshot generator | ||
239 | |||
240 | private XmlDocument Snapshot(Scene scene) | ||
241 | { | ||
242 | XmlDocument basedoc = new XmlDocument(); | ||
243 | XmlNode regionElement = MakeRegionNode(scene, basedoc); | ||
244 | |||
245 | regionElement.AppendChild(GetGridSnapshotData(basedoc)); | ||
246 | XmlNode regionData = basedoc.CreateNode(XmlNodeType.Element, "data", ""); | ||
247 | |||
248 | foreach (KeyValuePair<Scene, List<IDataSnapshotProvider>> dataprovider in m_dataproviders) | ||
249 | { | ||
250 | if (dataprovider.Key == scene) | ||
251 | { | ||
252 | foreach (IDataSnapshotProvider provider in dataprovider.Value) | ||
253 | { | ||
254 | XmlNode data = provider.RequestSnapshotData(basedoc); | ||
255 | regionData.AppendChild(data); | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | regionElement.AppendChild(regionData); | ||
261 | |||
262 | basedoc.AppendChild(regionElement); | ||
263 | |||
264 | return basedoc; | ||
265 | } | ||
266 | |||
267 | private XmlNode MakeRegionNode(Scene scene, XmlDocument basedoc) | ||
268 | { | ||
269 | XmlNode docElement = basedoc.CreateNode(XmlNodeType.Element, "region", ""); | ||
270 | |||
271 | XmlAttribute attr = basedoc.CreateAttribute("category"); | ||
272 | attr.Value = GetRegionCategory(scene); | ||
273 | docElement.Attributes.Append(attr); | ||
274 | |||
275 | attr = basedoc.CreateAttribute("entities"); | ||
276 | attr.Value = scene.Entities.Count.ToString(); | ||
277 | docElement.Attributes.Append(attr); | ||
278 | |||
279 | //attr = basedoc.CreateAttribute("parcels"); | ||
280 | //attr.Value = scene.LandManager.landList.Count.ToString(); | ||
281 | //docElement.Attributes.Append(attr); | ||
282 | |||
283 | |||
284 | XmlNode infoblock = basedoc.CreateNode(XmlNodeType.Element, "info", ""); | ||
285 | |||
286 | XmlNode infopiece = basedoc.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
287 | infopiece.InnerText = scene.RegionInfo.RegionID.ToString(); | ||
288 | infoblock.AppendChild(infopiece); | ||
289 | |||
290 | infopiece = basedoc.CreateNode(XmlNodeType.Element, "url", ""); | ||
291 | infopiece.InnerText = "http://" + m_hostname + ":" + m_listener_port; | ||
292 | infoblock.AppendChild(infopiece); | ||
293 | |||
294 | infopiece = basedoc.CreateNode(XmlNodeType.Element, "name", ""); | ||
295 | infopiece.InnerText = scene.RegionInfo.RegionName; | ||
296 | infoblock.AppendChild(infopiece); | ||
297 | |||
298 | docElement.AppendChild(infoblock); | ||
299 | |||
300 | return docElement; | ||
301 | } | ||
302 | |||
303 | private XmlNode GetGridSnapshotData(XmlDocument factory) | ||
304 | { | ||
305 | XmlNode griddata = factory.CreateNode(XmlNodeType.Element, "grid", ""); | ||
306 | |||
307 | foreach (KeyValuePair<String, String> GridData in m_gridinfo) | ||
308 | { | ||
309 | //TODO: make it lowercase tag names for diva | ||
310 | XmlNode childnode = factory.CreateNode(XmlNodeType.Element, GridData.Key, ""); | ||
311 | childnode.InnerText = GridData.Value; | ||
312 | griddata.AppendChild(childnode); | ||
313 | } | ||
314 | |||
315 | return griddata; | ||
316 | } | ||
317 | |||
318 | private String GetRegionCategory(Scene scene) | ||
319 | { | 227 | { |
228 | foreach (Scene scene in m_scenes) | ||
229 | if (scene.RegionInfo.RegionID == id) | ||
230 | return scene; | ||
320 | 231 | ||
321 | //Boolean choice between: | 232 | return null; |
322 | // "PG" - Mormontown | ||
323 | // "Mature" - Sodom and Gomorrah | ||
324 | // (Depreciated) "Patriotic Nigra Testing Sandbox" - Abandon Hope All Ye Who Enter Here | ||
325 | if ((scene.RegionInfo.EstateSettings.simAccess & Simulator.SimAccess.Mature) == Simulator.SimAccess.Mature) | ||
326 | { | ||
327 | return "Mature"; | ||
328 | } | ||
329 | else if ((scene.RegionInfo.EstateSettings.simAccess & Simulator.SimAccess.PG) == Simulator.SimAccess.PG) | ||
330 | { | ||
331 | return "PG"; | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | return "Unknown"; | ||
336 | } | ||
337 | } | 233 | } |
338 | 234 | ||
339 | /* Code's closed due to AIDS, See EstateSnapshot.cs for CURE | ||
340 | private XmlNode GetEstateSnapshotData(Scene scene, XmlDocument factory) | ||
341 | { | ||
342 | //Estate data section - contains who owns a set of sims and the name of the set. | ||
343 | //In Opensim all the estate names are the same as the Master Avatar (owner of the sim) | ||
344 | XmlNode estatedata = factory.CreateNode(XmlNodeType.Element, "estate", ""); | ||
345 | |||
346 | LLUUID ownerid = scene.RegionInfo.MasterAvatarAssignedUUID; | ||
347 | String firstname = scene.RegionInfo.MasterAvatarFirstName; | ||
348 | String lastname = scene.RegionInfo.MasterAvatarLastName; | ||
349 | String hostname = scene.RegionInfo.ExternalHostName; | ||
350 | |||
351 | XmlNode user = factory.CreateNode(XmlNodeType.Element, "owner", ""); | ||
352 | |||
353 | XmlNode username = factory.CreateNode(XmlNodeType.Element, "name", ""); | ||
354 | username.InnerText = firstname + " " + lastname; | ||
355 | user.AppendChild(username); | ||
356 | |||
357 | XmlNode useruuid = factory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
358 | useruuid.InnerText = ownerid.ToString(); | ||
359 | user.AppendChild(useruuid); | ||
360 | |||
361 | estatedata.AppendChild(user); | ||
362 | |||
363 | return estatedata; | ||
364 | } */ | ||
365 | |||
366 | #endregion | 235 | #endregion |
367 | 236 | ||
368 | #region [Public] Snapshot storage functions | 237 | #region [Public] Snapshot storage functions |
369 | 238 | ||
370 | public void MakeNewSnapshot() | ||
371 | { | ||
372 | foreach (Scene scene in m_scenes) | ||
373 | { | ||
374 | XmlDocument snapshot = Snapshot(scene); | ||
375 | |||
376 | string path = DataFileName(scene); | ||
377 | |||
378 | try | ||
379 | { | ||
380 | using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) | ||
381 | { | ||
382 | snapXWriter.Formatting = Formatting.Indented; | ||
383 | snapXWriter.WriteStartDocument(); | ||
384 | snapshot.WriteTo(snapXWriter); | ||
385 | snapXWriter.WriteEndDocument(); | ||
386 | |||
387 | m_lastSnapshot++; | ||
388 | } | ||
389 | } | ||
390 | catch (Exception e) | ||
391 | { | ||
392 | m_log.Warn("[DATASNAPSHOT]: Caught unknown exception while trying to save snapshot: " + path + "\n" + e.ToString()); | ||
393 | } | ||
394 | m_log.Info("[DATASNAPSHOT]: Made external data snapshot " + path); | ||
395 | } | ||
396 | } | ||
397 | |||
398 | /** | 239 | /** |
399 | * Reply to the http request | 240 | * Reply to the http request |
400 | */ | 241 | */ |
@@ -410,30 +251,16 @@ namespace OpenSim.Region.DataSnapshot | |||
410 | { | 251 | { |
411 | foreach (Scene scene in m_scenes) | 252 | foreach (Scene scene in m_scenes) |
412 | { | 253 | { |
413 | string path = DataFileName(scene); | 254 | regiondata.AppendChild(m_snapStore.GetScene(scene, requestedSnap)); |
414 | XmlDocument regionSnap = new XmlDocument(); | ||
415 | regionSnap.PreserveWhitespace = true; | ||
416 | |||
417 | regionSnap.Load(path); | ||
418 | XmlNode nodeOrig = regionSnap["region"]; | ||
419 | XmlNode nodeDest = requestedSnap.ImportNode(nodeOrig, true); | ||
420 | //requestedSnap.AppendChild(nodeDest); | ||
421 | |||
422 | regiondata.AppendChild(requestedSnap.CreateWhitespace("\r\n")); | ||
423 | regiondata.AppendChild(nodeDest); | ||
424 | } | 255 | } |
425 | } | 256 | } |
426 | else | 257 | else |
427 | { | 258 | { |
428 | Scene scene = SceneForName(regionName); | 259 | Scene scene = SceneForName(regionName); |
429 | requestedSnap.Load(DataFileName(scene)); | 260 | regiondata.AppendChild(m_snapStore.GetScene(scene, requestedSnap)); |
430 | } | 261 | } |
431 | // requestedSnap.InsertBefore(requestedSnap.CreateXmlDeclaration("1.0", null, null), | ||
432 | // requestedSnap.DocumentElement); | ||
433 | requestedSnap.AppendChild(regiondata); | 262 | requestedSnap.AppendChild(regiondata); |
434 | regiondata.AppendChild(requestedSnap.CreateWhitespace("\r\n")); | 263 | regiondata.AppendChild(requestedSnap.CreateWhitespace("\r\n")); |
435 | |||
436 | |||
437 | } | 264 | } |
438 | catch (XmlException e) | 265 | catch (XmlException e) |
439 | { | 266 | { |
@@ -469,16 +296,6 @@ namespace OpenSim.Region.DataSnapshot | |||
469 | 296 | ||
470 | #endregion | 297 | #endregion |
471 | 298 | ||
472 | #region Event callbacks | ||
473 | |||
474 | private void SnapshotTimerCallback(object timer, ElapsedEventArgs args) | ||
475 | { | ||
476 | MakeNewSnapshot(); | ||
477 | //Add extra calls here | ||
478 | } | ||
479 | |||
480 | #endregion | ||
481 | |||
482 | #region External data services | 299 | #region External data services |
483 | private void NotifyDataServices(string servicesStr) | 300 | private void NotifyDataServices(string servicesStr) |
484 | { | 301 | { |
@@ -524,5 +341,85 @@ namespace OpenSim.Region.DataSnapshot | |||
524 | 341 | ||
525 | } | 342 | } |
526 | #endregion | 343 | #endregion |
344 | |||
345 | #region Latency-based update functions | ||
346 | |||
347 | public void MarkDataStale(IDataSnapshotProvider provider) | ||
348 | { | ||
349 | //Behavior here: Wait m_period seconds, then update if there has not been a request in m_period seconds | ||
350 | //or m_maxStales has been exceeded | ||
351 | m_stales++; | ||
352 | |||
353 | if ((m_stales >= m_maxStales) && m_periodPassed) | ||
354 | SnapshotTimerCallback(m_periodic, null); | ||
355 | else if (m_periodic.Enabled == false) | ||
356 | m_periodic.Start(); | ||
357 | else | ||
358 | { | ||
359 | m_periodic.Stop(); | ||
360 | m_periodic.Start(); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | private void SnapshotTimerCallback(object timer, ElapsedEventArgs args) | ||
365 | { | ||
366 | m_log.Debug("[DATASNAPSHOT]: Marking scenes for snapshot updates."); | ||
367 | |||
368 | //Finally generate those snapshot updates | ||
369 | MakeEverythingStale(); | ||
370 | |||
371 | //Stop the update delay timer | ||
372 | m_periodic.Stop(); | ||
373 | |||
374 | //Reset the eligibility flag and timer | ||
375 | m_periodPassed = false; | ||
376 | m_passedCheck.Stop(); | ||
377 | m_passedCheck.Start(); | ||
378 | } | ||
379 | |||
380 | private void UpdateEligibilityCallback(object timer, ElapsedEventArgs args) | ||
381 | { | ||
382 | //Set eligibility, so we can start making updates | ||
383 | m_periodPassed = true; | ||
384 | } | ||
385 | |||
386 | public void MakeEverythingStale() | ||
387 | { | ||
388 | m_log.Debug("[DATASNAPSHOT]: Marking all scenes as stale."); | ||
389 | foreach (Scene scene in m_scenes) | ||
390 | { | ||
391 | m_snapStore.ForceSceneStale(scene); | ||
392 | } | ||
393 | } | ||
394 | |||
395 | #endregion | ||
396 | |||
397 | public void OnSimRestart(RegionInfo thisRegion) | ||
398 | { | ||
399 | m_log.Info("[DATASNAPSHOT]: Region " + thisRegion.RegionName + " is restarting, removing from indexing"); | ||
400 | Scene restartedScene = SceneForUUID(thisRegion.RegionID); | ||
401 | |||
402 | m_scenes.Remove(restartedScene); | ||
403 | m_snapStore.RemoveScene(restartedScene); | ||
404 | |||
405 | //Getting around the fact that we can't remove objects from a collection we are enumerating over | ||
406 | List<IDataSnapshotProvider> providersToRemove = new List<IDataSnapshotProvider>(); | ||
407 | |||
408 | foreach (IDataSnapshotProvider provider in m_dataproviders) | ||
409 | { | ||
410 | if (provider.GetParentScene == restartedScene) | ||
411 | { | ||
412 | providersToRemove.Add(provider); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | foreach (IDataSnapshotProvider provider in providersToRemove) | ||
417 | { | ||
418 | m_dataproviders.Remove(provider); | ||
419 | m_snapStore.RemoveProvider(provider); | ||
420 | } | ||
421 | |||
422 | m_snapStore.RemoveScene(restartedScene); | ||
423 | } | ||
527 | } | 424 | } |
528 | } | 425 | } |