import {Express, Router} from "express"; import Logger from "./Logger"; import {sleep} from "./Utils"; import Application from "./Application"; export default abstract class ApplicationComponent { private val?: T; protected app?: Application; public abstract async start(app: Express, router: Router): Promise; public abstract async stop(): Promise; protected export(val: T) { this.val = val; } public import(): T { if (!this.val) throw 'Cannot import if nothing was exported.'; return this.val; } public setApp(app: Application) { this.app = app; } protected async prepare(name: string, prepare: () => Promise): Promise { 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 { 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}.`); } } }