diff --git a/packages/sequencer/src/sequencer/executor/Sequencer.ts b/packages/sequencer/src/sequencer/executor/Sequencer.ts index 380faaee..5424fb60 100644 --- a/packages/sequencer/src/sequencer/executor/Sequencer.ts +++ b/packages/sequencer/src/sequencer/executor/Sequencer.ts @@ -66,6 +66,14 @@ export class Sequencer * modules to start each */ public async start() { + // The sequencer uses Tysringe to resolve modules (and their dependencies) + // and then starts them. However, this can be problematic as although Tysringe may resolve + // dependencies, it doesn't actually start them. For example, a database may be created, + // but the connection strings, etc, won't be constructed until it's started, and this may + // cause an error if a module that relies on it is started first. The way to fix this is + // ensure that we start modules based on the order they were resolved. + // We iterate through the methods three times: + this.useDependencyFactory(this.container.resolve(MethodIdFactory)); // Log startup info @@ -75,6 +83,8 @@ export class Sequencer log.info("Starting sequencer..."); log.info("Modules:", moduleClassNames); + // Iteration #1: We invoke the afterResolution feature for the container + // to ensure every time a module is resolved it gets recorded. const orderedModules: Extract[] = []; // eslint-disable-next-line guard-for-in for (const moduleName in this.definition.modules) { @@ -88,6 +98,8 @@ export class Sequencer } ); } + // Iteration #2: We resolve each module and thus populate + // the orderedModules list to understand the sequencing. // eslint-disable-next-line guard-for-in for (const moduleName in this.definition.modules) { const sequencerModule = this.resolve(moduleName); @@ -96,6 +108,8 @@ export class Sequencer ); } + // Iteration #3: We now iterate though the orderedModules list + // and start the modules in the order they were resolved. for (const moduleName of orderedModules) { const sequencerModule = this.resolve(moduleName); // eslint-disable-next-line no-await-in-loop