aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Monitoring/WorkManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Monitoring/WorkManager.cs')
-rw-r--r--OpenSim/Framework/Monitoring/WorkManager.cs48
1 files changed, 26 insertions, 22 deletions
diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs
index d1a74ce..5d9b185 100644
--- a/OpenSim/Framework/Monitoring/WorkManager.cs
+++ b/OpenSim/Framework/Monitoring/WorkManager.cs
@@ -36,16 +36,16 @@ namespace OpenSim.Framework.Monitoring
36 /// Manages various work items in the simulator. 36 /// Manages various work items in the simulator.
37 /// </summary> 37 /// </summary>
38 /// <remarks> 38 /// <remarks>
39 /// Currently, here work can be started 39 /// Currently, here work can be started
40 /// * As a long-running and monitored thread. 40 /// * As a long-running and monitored thread.
41 /// * In a thread that will never timeout but where the job is expected to eventually complete. 41 /// * In a thread that will never timeout but where the job is expected to eventually complete.
42 /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins). 42 /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins).
43 /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps, 43 /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps,
44 /// network waits, etc.). 44 /// network waits, etc.).
45 /// 45 ///
46 /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse 46 /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse
47 /// range of sources (client actions, incoming network, outgoing network calls, etc.). 47 /// range of sources (client actions, incoming network, outgoing network calls, etc.).
48 /// 48 ///
49 /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to 49 /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to
50 /// WorkManager.RunInThreadPool(). 50 /// WorkManager.RunInThreadPool().
51 /// </remarks> 51 /// </remarks>
@@ -57,7 +57,7 @@ namespace OpenSim.Framework.Monitoring
57 57
58 static WorkManager() 58 static WorkManager()
59 { 59 {
60 JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE"); 60 JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE", 30000);
61 61
62 StatsManager.RegisterStat( 62 StatsManager.RegisterStat(
63 new Stat( 63 new Stat(
@@ -82,6 +82,12 @@ namespace OpenSim.Framework.Monitoring
82 HandleControlCommand); 82 HandleControlCommand);
83 } 83 }
84 84
85 public static void Stop()
86 {
87 JobEngine.Stop();
88 Watchdog.Stop();
89 }
90
85 /// <summary> 91 /// <summary>
86 /// Start a new long-lived thread. 92 /// Start a new long-lived thread.
87 /// </summary> 93 /// </summary>
@@ -121,6 +127,7 @@ namespace OpenSim.Framework.Monitoring
121 Thread thread = new Thread(start); 127 Thread thread = new Thread(start);
122 thread.Priority = priority; 128 thread.Priority = priority;
123 thread.IsBackground = isBackground; 129 thread.IsBackground = isBackground;
130 thread.Name = name;
124 131
125 Watchdog.ThreadWatchdogInfo twi 132 Watchdog.ThreadWatchdogInfo twi
126 = new Watchdog.ThreadWatchdogInfo(thread, timeout, name) 133 = new Watchdog.ThreadWatchdogInfo(thread, timeout, name)
@@ -129,7 +136,6 @@ namespace OpenSim.Framework.Monitoring
129 Watchdog.AddThread(twi, name, log:log); 136 Watchdog.AddThread(twi, name, log:log);
130 137
131 thread.Start(); 138 thread.Start();
132 thread.Name = name;
133 139
134 return thread; 140 return thread;
135 } 141 }
@@ -143,7 +149,7 @@ namespace OpenSim.Framework.Monitoring
143 /// <param name="name">Name of the thread</param> 149 /// <param name="name">Name of the thread</param>
144 public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false) 150 public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false)
145 { 151 {
146 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) 152 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
147 { 153 {
148 Culture.SetCurrentCulture(); 154 Culture.SetCurrentCulture();
149 callback(obj); 155 callback(obj);
@@ -168,7 +174,7 @@ namespace OpenSim.Framework.Monitoring
168 } 174 }
169 175
170 /// <summary> 176 /// <summary>
171 /// Run the callback via a threadpool thread. 177 /// Run the callback via a threadpool thread.
172 /// </summary> 178 /// </summary>
173 /// <remarks> 179 /// <remarks>
174 /// Such jobs may run after some delay but must always complete. 180 /// Such jobs may run after some delay but must always complete.
@@ -176,9 +182,9 @@ namespace OpenSim.Framework.Monitoring
176 /// <param name="callback"></param> 182 /// <param name="callback"></param>
177 /// <param name="obj"></param> 183 /// <param name="obj"></param>
178 /// <param name="name">The name of the job. This is used in monitoring and debugging.</param> 184 /// <param name="name">The name of the job. This is used in monitoring and debugging.</param>
179 public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name) 185 public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name, bool timeout = true)
180 { 186 {
181 Util.FireAndForget(callback, obj, name); 187 Util.FireAndForget(callback, obj, name, timeout);
182 } 188 }
183 189
184 /// <summary> 190 /// <summary>
@@ -187,17 +193,17 @@ namespace OpenSim.Framework.Monitoring
187 /// <remarks> 193 /// <remarks>
188 /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job 194 /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job
189 /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is 195 /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is
190 /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to 196 /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to
191 /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small 197 /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small
192 /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more 198 /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more
193 /// sophisticated implementation could perform jobs concurrently when the server is under low load. 199 /// sophisticated implementation could perform jobs concurrently when the server is under low load.
194 /// 200 ///
195 /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any 201 /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any
196 /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine 202 /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine
197 /// beyond a single thread will require considerable thought. 203 /// beyond a single thread will require considerable thought.
198 /// 204 ///
199 /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot 205 /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot
200 /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues 206 /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues
201 /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where 207 /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where
202 /// the job engine could be improved and so CPU utilization improved by better management of concurrency within 208 /// the job engine could be improved and so CPU utilization improved by better management of concurrency within
203 /// OpenSimulator. 209 /// OpenSimulator.
@@ -211,10 +217,10 @@ namespace OpenSim.Framework.Monitoring
211 /// <param name="log">If set to true then extra logging is performed.</param> 217 /// <param name="log">If set to true then extra logging is performed.</param>
212 public static void RunJob( 218 public static void RunJob(
213 string jobType, WaitCallback callback, object obj, string name, 219 string jobType, WaitCallback callback, object obj, string name,
214 bool canRunInThisThread = false, bool mustNotTimeout = false, 220 bool canRunInThisThread = false, bool mustNotTimeout = false,
215 bool log = false) 221 bool log = false)
216 { 222 {
217 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) 223 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
218 { 224 {
219 Culture.SetCurrentCulture(); 225 Culture.SetCurrentCulture();
220 callback(obj); 226 callback(obj);
@@ -225,10 +231,8 @@ namespace OpenSim.Framework.Monitoring
225 JobEngine.QueueJob(name, () => callback(obj)); 231 JobEngine.QueueJob(name, () => callback(obj));
226 else if (canRunInThisThread) 232 else if (canRunInThisThread)
227 callback(obj); 233 callback(obj);
228 else if (mustNotTimeout)
229 RunInThread(callback, obj, name, log);
230 else 234 else
231 Util.FireAndForget(callback, obj, name); 235 Util.FireAndForget(callback, obj, name, !mustNotTimeout);
232 } 236 }
233 237
234 private static void HandleControlCommand(string module, string[] args) 238 private static void HandleControlCommand(string module, string[] args)
@@ -272,16 +276,16 @@ namespace OpenSim.Framework.Monitoring
272 MainConsole.Instance.Output("Usage: debug jobengine log <level>"); 276 MainConsole.Instance.Output("Usage: debug jobengine log <level>");
273 return; 277 return;
274 } 278 }
275 279
276 // int logLevel; 280 // int logLevel;
277 int logLevel = int.Parse(args[3]); 281 int logLevel = int.Parse(args[3]);
278 // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel)) 282 // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
279 // { 283 // {
280 JobEngine.LogLevel = logLevel; 284 JobEngine.LogLevel = logLevel;
281 MainConsole.Instance.OutputFormat("Set debug log level to {0}", JobEngine.LogLevel); 285 MainConsole.Instance.OutputFormat("Set debug log level to {0}", JobEngine.LogLevel);
282 // } 286 // }
283 } 287 }
284 else 288 else
285 { 289 {
286 MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand); 290 MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
287 } 291 }