aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs69
1 files changed, 63 insertions, 6 deletions
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
index 54b9b09..98127b7 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
@@ -35,7 +35,9 @@ using log4net;
35using Nini; 35using Nini;
36using Nini.Config; 36using Nini.Config;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Statistics;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
39 41
40 42
41/* 43/*
@@ -319,6 +321,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
319 321
320 void HandleElapsed (object sender, ElapsedEventArgs e) 322 void HandleElapsed (object sender, ElapsedEventArgs e)
321 { 323 {
324 //TODO?: heuristic thresholds are per-region, so we should probably run heuristics once per region
325 //XXX: Running heuristics once per region could add undue performance penalty for something that's supposed to
326 //check whether the region is too busy! Especially on sims with LOTS of regions.
327 //Alternative: make heuristics thresholds global to the module rather than per-region. Less flexible,
328 // but would allow us to be semantically correct while being easier on perf.
329 //Alternative 2: Run heuristics once per unique set of heuristics threshold parameters! Ay yi yi...
322 if (m_closed) 330 if (m_closed)
323 return; 331 return;
324 bool heuristicsRun = false; 332 bool heuristicsRun = false;
@@ -333,15 +341,18 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
333 //Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region. 341 //Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region.
334 if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics) { 342 if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics) {
335 doRegionBackup (scene); 343 doRegionBackup (scene);
336 //Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off! 344 //Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off!
337 } else if (heuristics && heuristicsRun && !heuristicsPassed) { 345 } else if (heuristics && heuristicsRun && !heuristicsPassed) {
346 m_log.Info ("[AUTO BACKUP MODULE]: Heuristics: too busy to backup " + scene.RegionInfo.RegionName + " right now.");
338 continue; 347 continue;
339 //Logical Deduction: heuristics are on but haven't been run 348 //Logical Deduction: heuristics are on but haven't been run
340 } else { 349 } else {
341 heuristicsPassed = RunHeuristics (); 350 heuristicsPassed = RunHeuristics (scene);
342 heuristicsRun = true; 351 heuristicsRun = true;
343 if (!heuristicsPassed) 352 if (!heuristicsPassed) {
353 m_log.Info ("[AUTO BACKUP MODULE]: Heuristics: too busy to backup " + scene.RegionInfo.RegionName + " right now.");
344 continue; 354 continue;
355 }
345 doRegionBackup (scene); 356 doRegionBackup (scene);
346 } 357 }
347 } 358 }
@@ -349,6 +360,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
349 360
350 void doRegionBackup (IScene scene) 361 void doRegionBackup (IScene scene)
351 { 362 {
363 if (scene.RegionStatus != RegionStatus.Up) {
364 //We won't backup a region that isn't operating normally.
365 m_log.Warn ("[AUTO BACKUP MODULE]: Not backing up region " + scene.RegionInfo.RegionName + " because its status is " + scene.RegionStatus.ToString ());
366 return;
367 }
368
352 AutoBackupModuleState state = states[scene]; 369 AutoBackupModuleState state = states[scene];
353 IRegionArchiverModule iram = scene.RequestModuleInterface<IRegionArchiverModule> (); 370 IRegionArchiverModule iram = scene.RequestModuleInterface<IRegionArchiverModule> ();
354 string savePath = BuildOarPath (scene.RegionInfo.RegionName, state.GetBackupDir (), state.GetNamingType ()); 371 string savePath = BuildOarPath (scene.RegionInfo.RegionName, state.GetBackupDir (), state.GetNamingType ());
@@ -454,9 +471,49 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
454 return uniqueFile.FullName; 471 return uniqueFile.FullName;
455 } 472 }
456 473
457 private bool RunHeuristics () 474 /*
475 * Return value of true ==> not too busy; false ==> too busy to backup an OAR right now, or error.
476 * */
477 private bool RunHeuristics (IScene region)
478 {
479 try {
480 return RunTimeDilationHeuristic (region) && RunAgentLimitHeuristic (region);
481 } catch (Exception e) {
482 m_log.Warn ("[AUTO BACKUP MODULE]: Exception in RunHeuristics", e);
483 return false;
484 }
485 }
486
487 /*
488 * If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5),
489 * then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR).
490 * AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy".
491 * Return value of "true" ==> not too busy. Return value of "false" ==> too busy!
492 * */
493 private bool RunTimeDilationHeuristic (IScene region)
458 { 494 {
459 return true; 495 string regionName = region.RegionInfo.RegionName;
496 return region.TimeDilation >= m_configSource.Configs["AutoBackupModule"].GetFloat (regionName + ".AutoBackupDilationThreshold", 0.5f);
497 }
498
499 /*
500 * If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10),
501 * then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR).
502 * AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy".
503 * Return value of "true" ==> not too busy. Return value of "false" ==> too busy!
504 * */
505 private bool RunAgentLimitHeuristic (IScene region)
506 {
507 string regionName = region.RegionInfo.RegionName;
508 try {
509 Scene scene = (Scene)region;
510 //TODO: Why isn't GetRootAgentCount() a method in the IScene interface? Seems generally useful...
511 return scene.GetRootAgentCount () <= m_configSource.Configs["AutoBackupModule"].GetInt (regionName + ".AutoBackupAgentThreshold", 10);
512 } catch (InvalidCastException ice) {
513 m_log.Debug ("[AUTO BACKUP MODULE]: I NEED MAINTENANCE: IScene is not a Scene; can't get root agent count!");
514 return true;
515 //Non-obstructionist safest answer...
516 }
460 } 517 }
461 518
462 private void ExecuteScript (string scriptName, string savePath) 519 private void ExecuteScript (string scriptName, string savePath)