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