Browse Source

Refactor the microservice lifecycle so that exec returns an exit code

dev
David Ludwig 4 years ago
parent
commit
c629768715
1 changed files with 65 additions and 12 deletions
  1. +65
    -12
      packages/microservice/src/Microservice.ts

+ 65
- 12
packages/microservice/src/Microservice.ts View File

@ -13,6 +13,18 @@ interface InternalServiceMap {
*/ */
type InternalServiceConstructor<T extends Microservice = Microservice> = new (app: T) => InternalService<T>; type InternalServiceConstructor<T extends Microservice = Microservice> = new (app: T) => InternalService<T>;
/**
* Microservice states
*/
export enum MicroserviceState {
Idling,
Booting,
Starting,
Running,
Quitting,
Finished
}
/** /**
* The main application class * The main application class
*/ */
@ -24,10 +36,20 @@ export class Microservice
private static __instance: Microservice; private static __instance: Microservice;
/** /**
* All available InternalServices
* A handler function to quit the microservice application
*/
private __quitHandler!: (value: number | PromiseLike<number>) => void;
/**
* All available services
*/ */
protected services: InternalServiceMap = {}; protected services: InternalServiceMap = {};
/**
* The current state of the microservice
*/
protected state: MicroserviceState;
/** /**
* Return the current application instance * Return the current application instance
*/ */
@ -40,6 +62,7 @@ export class Microservice
*/ */
public constructor() { public constructor() {
Microservice.__instance = this; Microservice.__instance = this;
this.state = MicroserviceState.Idling;
} }
// Overridable -------------------------------------------------------------------------------- // Overridable --------------------------------------------------------------------------------
@ -52,7 +75,7 @@ export class Microservice
// Application Management ---------------------------------------------------------------------- // Application Management ----------------------------------------------------------------------
/** /**
* Boot the application and all of the InternalServices
* Boot the application and all of the services
*/ */
protected async boot() { protected async boot() {
let InternalServices = Object.values(this.services); let InternalServices = Object.values(this.services);
@ -71,19 +94,49 @@ export class Microservice
* Start the application * Start the application
*/ */
public async exec() { public async exec() {
await this.boot();
await this.onStart();
for (let InternalService of Object.values(this.services)) {
InternalService.start();
// Exit if not in an idling state
if (this.state !== MicroserviceState.Idling) {
return -1;
}
try {
// Boot the microservice
this.state = MicroserviceState.Booting;
await this.boot();
// Start the microservice
this.state = MicroserviceState.Starting
await this.onStart();
for (let InternalService of Object.values(this.services)) {
InternalService.start();
}
} catch(e) {
console.log("Failed to start the microservice");
return 1;
} }
// Run the microservice
this.state = MicroserviceState.Running;
let exitCode = await new Promise<number>((resolve) => this.__quitHandler = resolve);
// Shutdown the microservice
await this.shutdown().catch(() => {
console.log("Error ocurred during shutdown...");
exitCode = 1;
});
// Return the exit code
return exitCode;
} }
/** /**
* Quit the application * Quit the application
*/ */
public async quit(code: number = 0) { public async quit(code: number = 0) {
await this.shutdown();
process.exit(code);
if (this.state !== MicroserviceState.Running) {
return;
}
this.__quitHandler(code);
} }
// InternalService Management -------------------------------------------------------------------------- // InternalService Management --------------------------------------------------------------------------
@ -91,7 +144,7 @@ export class Microservice
/** /**
* Install InternalServices into the application * Install InternalServices into the application
*/ */
protected installServices<T extends Microservice>(this: T, InternalServices: InternalServiceConstructor<T>[]) {
public installServices<T extends Microservice>(this: T, InternalServices: InternalServiceConstructor<T>[]) {
for (let InternalServiceClass of InternalServices) { for (let InternalServiceClass of InternalServices) {
this.installService(InternalServiceClass); this.installService(InternalServiceClass);
} }
@ -100,20 +153,20 @@ export class Microservice
/** /**
* Install a InternalService into the application * Install a InternalService into the application
*/ */
protected installService<T extends Microservice>(this: T, InternalServiceClass: InternalServiceConstructor<T>) {
public installService<T extends Microservice>(this: T, InternalServiceClass: InternalServiceConstructor<T>) {
let InternalService = new InternalServiceClass(this); let InternalService = new InternalServiceClass(this);
this.services[InternalService.name] = InternalService; this.services[InternalService.name] = InternalService;
} }
/** /**
* Get all available InternalServices
* Get all available services
*/ */
public serviceList() { public serviceList() {
return Object.keys(this.services); return Object.keys(this.services);
} }
/** /**
* Get an application InternalService instance
* Get an application services instance
*/ */
public service<T extends InternalService<Microservice>>(InternalServiceName: string) { public service<T extends InternalService<Microservice>>(InternalServiceName: string) {
assert(InternalServiceName in this.services); assert(InternalServiceName in this.services);


Loading…
Cancel
Save