Mercurial > projects > mde
comparison mde/scheduler/Init.d @ 25:2c28ee04a4ed
Some minor and some futile efforts.
Played around with init functions, had problems, gave up and put them back.
Removed idea for multiple init stages; it's not good for performance or simplicity.
Adjusted exception messages.
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Thu, 03 Apr 2008 17:26:52 +0100 |
parents | 32eff0e01c05 |
children | 611f7b9063c6 |
comparison
equal
deleted
inserted
replaced
24:32eff0e01c05 | 25:2c28ee04a4ed |
---|---|
20 * deinitialisation of the program. It does not, however, provide much of the (de)initialisation | 20 * deinitialisation of the program. It does not, however, provide much of the (de)initialisation |
21 * code; with the exception of that for the logger. | 21 * code; with the exception of that for the logger. |
22 *************************************************************************************************/ | 22 *************************************************************************************************/ |
23 module mde.scheduler.Init; | 23 module mde.scheduler.Init; |
24 | 24 |
25 import mde.scheduler.InitStage; | 25 import mde.scheduler.InitFunctions; |
26 import mde.scheduler.exception; | 26 import mde.scheduler.exception; |
27 | 27 |
28 import mde.options; | 28 import mde.options; |
29 import paths = mde.resource.paths; | 29 import paths = mde.resource.paths; |
30 import mde.exception; | 30 import mde.exception; |
34 import tango.core.Exception; | 34 import tango.core.Exception; |
35 import tango.stdc.stringz : fromStringz; | 35 import tango.stdc.stringz : fromStringz; |
36 import tango.util.log.Log : Log, Logger; | 36 import tango.util.log.Log : Log, Logger; |
37 import tango.util.log.ConsoleAppender : ConsoleAppender; | 37 import tango.util.log.ConsoleAppender : ConsoleAppender; |
38 | 38 |
39 version = SwitchAppender; | 39 //version = SwitchAppender; |
40 version (SwitchAppender) { // My own variation, currently just a test | 40 version (SwitchAppender) { // My own variation, currently just a test |
41 import tango.util.log.SwitchingFileAppender : SwitchingFileAppender; | 41 import tango.util.log.SwitchingFileAppender : SwitchingFileAppender; |
42 } else { | 42 } else { |
43 import tango.util.log.RollingFileAppender : RollingFileAppender; | 43 import tango.util.log.RollingFileAppender : RollingFileAppender; |
44 } | 44 } |
90 * A scope class created at beginning of the program and destroyed at the end; thus the CTOR | 90 * A scope class created at beginning of the program and destroyed at the end; thus the CTOR |
91 * handles program initialisation and the DTOR handles program cleanup. | 91 * handles program initialisation and the DTOR handles program cleanup. |
92 */ | 92 */ |
93 scope class Init | 93 scope class Init |
94 { | 94 { |
95 //private bool failure = false; // set true on failure during init, so that clean | |
95 private static Logger logger; | 96 private static Logger logger; |
96 static this() { | 97 static this() { |
97 logger = Log.getLogger ("mde.scheduler.Init.Init"); | 98 logger = Log.getLogger ("mde.scheduler.Init.Init"); |
98 } | 99 } |
99 | 100 |
119 * Most work is probably disk access | 120 * Most work is probably disk access |
120 * It's a really good idea to let the options apply to all other loading. */ | 121 * It's a really good idea to let the options apply to all other loading. */ |
121 try { | 122 try { |
122 Options.load(); | 123 Options.load(); |
123 } catch (optionsLoadException e) { | 124 } catch (optionsLoadException e) { |
124 throw new InitException ("Loading options failed; message: " ~ e.msg); | 125 throw new InitException ("Loading options failed: " ~ e.msg); |
125 } | 126 } |
126 | 127 |
127 // Now re-set the logging level: | 128 // Now re-set the logging level: |
128 Log.getRootLogger.setLevel (cast(Log.Level) miscOpts.logLevel, true); // set the stored log level | 129 Log.getRootLogger.setLevel (cast(Log.Level) miscOpts.logLevel, true); // set the stored log level |
129 //END Pre-init | 130 //END Pre-init |
133 /* Call init functions. | 134 /* Call init functions. |
134 * | 135 * |
135 * Current method is to try using threads, and on failure assume no threads were actually | 136 * Current method is to try using threads, and on failure assume no threads were actually |
136 * created and run functions in a non-threaded manner. */ | 137 * created and run functions in a non-threaded manner. */ |
137 | 138 |
138 // init2 | |
139 cleanupStages ~= &cleanup2; // add appropriate cleanup stage | |
140 try { | 139 try { |
141 debug logger.trace ("Init: init2"); | 140 if (runStageThreaded (init)) runStageForward (init); |
142 if (runStageThreaded (init2)) runStageForward (init2); | |
143 } | 141 } |
144 catch (InitStageException) { // This init stage failed. | 142 catch (InitStageException) { // This init stage failed. |
145 debug logger.trace ("Init: init2 failed"); | 143 // FIXME: check DTOR still runs |
146 runCleanupStages(); | 144 throw new InitException ("An init function failed (see above message(s))"); |
147 throw new InitException ("Initialisation failed during stage init2"); | |
148 } | |
149 | |
150 // init4 | |
151 cleanupStages ~= &cleanup4; // add appropriate cleanup stage | |
152 try { | |
153 debug logger.trace ("Init: init4"); | |
154 if (runStageThreaded (init4)) runStageForward (init4); | |
155 } | |
156 catch (InitStageException) { // This init stage failed. | |
157 debug logger.trace ("Init: init4 failed"); | |
158 runCleanupStages(); | |
159 throw new InitException ("Initialisation failed during stage init4"); | |
160 } | 145 } |
161 //END Init | 146 //END Init |
162 | 147 |
163 debug logger.trace ("Init: done"); | 148 debug logger.trace ("Init: done"); |
164 } | 149 } |
166 /** DTOR - runs cleanup functions. */ | 151 /** DTOR - runs cleanup functions. */ |
167 ~this() | 152 ~this() |
168 { | 153 { |
169 debug logger.trace ("Cleanup: starting"); | 154 debug logger.trace ("Cleanup: starting"); |
170 | 155 |
171 // cleanup1: | |
172 Options.save(); // save options... do so here for now | 156 Options.save(); // save options... do so here for now |
173 | 157 |
174 // cleanup2, 4: | 158 // General cleanup: |
175 runCleanupStages(); | 159 try { |
160 if (runStageThreaded (cleanup)) runStageReverse (cleanup); | |
161 } | |
162 catch (InitStageException) { | |
163 // Nothing else to do but report: | |
164 logger.error ("One or more cleanup functions failed!"); | |
165 } | |
176 | 166 |
177 debug logger.trace ("Cleanup: done"); | 167 debug logger.trace ("Cleanup: done"); |
178 } | 168 } |
179 | 169 |
180 | 170 |
257 return false; // Done successfully | 247 return false; // Done successfully |
258 } | 248 } |
259 } | 249 } |
260 //END runStage... | 250 //END runStage... |
261 | 251 |
262 private { | |
263 InitStage*[] cleanupStages; // All cleanup stages needing to be run later. | |
264 void runCleanupStages () { | |
265 foreach_reverse (s; cleanupStages) { | |
266 try { | |
267 runStageReverse (*s); | |
268 } | |
269 catch (InitStageException) { | |
270 // We're cleaning up anyway, just report and continue | |
271 logger.error ("Cleanup function failed! Continuing..."); | |
272 } | |
273 } | |
274 cleanupStages = []; // All have been run, don't want them getting run again | |
275 } | |
276 } | |
277 | |
278 debug (mdeUnitTest) unittest { | 252 debug (mdeUnitTest) unittest { |
279 /* Fake init and cleanup. Use unittest-specific init and cleanup InitStages to avoid | 253 /* Fake init and cleanup. Use unittest-specific init and cleanup InitStages to avoid |
280 * messing other init/cleanup up. */ | 254 * messing other init/cleanup up. */ |
281 static InitStage initUT, cleanupUT; | 255 static InitStage initUT, cleanupUT; |
282 | 256 |