import { InternalService } from "./InternalService";
|
|
import assert from "assert";
|
|
|
|
/**
|
|
* Application InternalService map
|
|
*/
|
|
interface InternalServiceMap {
|
|
[name: string]: InternalService
|
|
}
|
|
|
|
/**
|
|
* The InternalService constructor type
|
|
*/
|
|
type InternalServiceConstructor<T extends Microservice = Microservice> = new (app: T) => InternalService<T>;
|
|
|
|
/**
|
|
* The main application class
|
|
*/
|
|
export class Microservice
|
|
{
|
|
/**
|
|
* Maintain a static reference to the application instance
|
|
*/
|
|
private static __instance: Microservice;
|
|
|
|
/**
|
|
* All available InternalServices
|
|
*/
|
|
protected services: InternalServiceMap = {};
|
|
|
|
/**
|
|
* Return the current application instance
|
|
*/
|
|
public static instance() {
|
|
return this.__instance;
|
|
}
|
|
|
|
/**
|
|
* Create a new application instance
|
|
*/
|
|
public constructor() {
|
|
Microservice.__instance = this;
|
|
}
|
|
|
|
// Overridable --------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Invoked when the application has finished booting
|
|
*/
|
|
protected onStart(): void|Promise<void> {}
|
|
|
|
// Application Management ----------------------------------------------------------------------
|
|
|
|
/**
|
|
* Boot the application and all of the InternalServices
|
|
*/
|
|
protected async boot() {
|
|
let InternalServices = Object.values(this.services);
|
|
return Promise.all(InternalServices.map(InternalService => InternalService.boot()));
|
|
}
|
|
|
|
/**
|
|
* Shutdown the application
|
|
*/
|
|
protected shutdown() {
|
|
let InternalServices = Object.values(this.services);
|
|
return Promise.all(InternalServices.map(InternalService => InternalService.shutdown()));
|
|
}
|
|
|
|
/**
|
|
* Start the application
|
|
*/
|
|
public async exec() {
|
|
await this.boot();
|
|
await this.onStart();
|
|
for (let InternalService of Object.values(this.services)) {
|
|
InternalService.start();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Quit the application
|
|
*/
|
|
public async quit(code: number = 0) {
|
|
await this.shutdown();
|
|
process.exit(code);
|
|
}
|
|
|
|
// InternalService Management --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Install InternalServices into the application
|
|
*/
|
|
protected installServices<T extends Microservice>(this: T, InternalServices: InternalServiceConstructor<T>[]) {
|
|
for (let InternalServiceClass of InternalServices) {
|
|
this.installService(InternalServiceClass);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Install a InternalService into the application
|
|
*/
|
|
protected installService<T extends Microservice>(this: T, InternalServiceClass: InternalServiceConstructor<T>) {
|
|
let InternalService = new InternalServiceClass(this);
|
|
this.services[InternalService.name] = InternalService;
|
|
}
|
|
|
|
/**
|
|
* Get all available InternalServices
|
|
*/
|
|
public serviceList() {
|
|
return Object.keys(this.services);
|
|
}
|
|
|
|
/**
|
|
* Get an application InternalService instance
|
|
*/
|
|
public service<T extends InternalService<Microservice>>(InternalServiceName: string) {
|
|
assert(InternalServiceName in this.services);
|
|
return <T>this.services[InternalServiceName];
|
|
}
|
|
}
|