48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
|
import {Express, Router} from "express";
|
||
|
import Logger from "./Logger";
|
||
|
import {sleep} from "./Utils";
|
||
|
|
||
|
export default abstract class ApplicationComponent<T> {
|
||
|
private val?: T;
|
||
|
|
||
|
public abstract async start(app: Express, router: Router): Promise<void>;
|
||
|
|
||
|
public abstract async stop(): Promise<void>;
|
||
|
|
||
|
protected export(val: T) {
|
||
|
this.val = val;
|
||
|
}
|
||
|
|
||
|
public import(): T {
|
||
|
if (!this.val) throw 'Cannot import if nothing was exported.';
|
||
|
return this.val;
|
||
|
}
|
||
|
|
||
|
protected async prepare(name: string, prepare: () => Promise<void>): Promise<void> {
|
||
|
let err;
|
||
|
do {
|
||
|
try {
|
||
|
await prepare();
|
||
|
err = null;
|
||
|
} catch (e) {
|
||
|
err = e;
|
||
|
Logger.error(err, `${name} failed to prepare; retrying in 5s...`)
|
||
|
await sleep(5000);
|
||
|
}
|
||
|
} while (err);
|
||
|
Logger.info(`${name} ready!`);
|
||
|
}
|
||
|
|
||
|
protected async close(thingName: string, thing: any, fn: Function): Promise<void> {
|
||
|
try {
|
||
|
await new Promise((resolve, reject) => fn.call(thing, (err: any) => {
|
||
|
if (err) reject(err);
|
||
|
else resolve();
|
||
|
}));
|
||
|
|
||
|
Logger.info(`${thingName} closed.`);
|
||
|
} catch (e) {
|
||
|
Logger.error(e, `An error occurred while closing the ${thingName}.`);
|
||
|
}
|
||
|
}
|
||
|
}
|