diff options
Diffstat (limited to 'OpenSim/Framework/Monitoring/WorkManager.cs')
-rw-r--r-- | OpenSim/Framework/Monitoring/WorkManager.cs | 48 |
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 | } |