From d44e29cccac29e1c1033c8d0ef1f09c0afba1adf Mon Sep 17 00:00:00 2001 From: Brian Faust Date: Thu, 22 Aug 2019 07:20:55 +0300 Subject: [PATCH] feat(core-kernel): required plugins to terminate on registration failure --- packages/core-blockchain/src/service-provider.ts | 4 ++++ .../src/service-provider.ts | 4 ++++ .../service-providers/boot-service-providers.ts | 11 ++++++++++- .../register-service-providers.ts | 14 +++++++------- .../src/contracts/core-kernel/application.ts | 16 ++++++++++++++-- packages/core-kernel/src/errors/kernel.ts | 16 ++++++++++++++++ .../core-kernel/src/support/service-provider.ts | 10 ++++++++++ .../core-logger-pino/src/service-provider.ts | 4 ++++ .../core-logger-signale/src/service-provider.ts | 4 ++++ .../core-logger-winston/src/service-provider.ts | 4 ++++ packages/core-p2p/src/service-provider.ts | 4 ++++ .../src/service-provider.ts | 4 ++++ 12 files changed, 85 insertions(+), 10 deletions(-) diff --git a/packages/core-blockchain/src/service-provider.ts b/packages/core-blockchain/src/service-provider.ts index fd344ab4f3..4c33ac9905 100644 --- a/packages/core-blockchain/src/service-provider.ts +++ b/packages/core-blockchain/src/service-provider.ts @@ -36,4 +36,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["blockchain"]; } + + public async required(): Promise { + return true; + } } diff --git a/packages/core-database-postgres/src/service-provider.ts b/packages/core-database-postgres/src/service-provider.ts index f2cf0b2487..e4fe23f9ac 100644 --- a/packages/core-database-postgres/src/service-provider.ts +++ b/packages/core-database-postgres/src/service-provider.ts @@ -33,4 +33,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["database"]; } + + public async required(): Promise { + return true; + } } diff --git a/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts b/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts index 16182fcaf1..153f9b9613 100644 --- a/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts +++ b/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts @@ -1,4 +1,5 @@ import { State } from "../../enums/event"; +import { FailedServiceProviderBoot } from "../../errors"; import { ServiceProviderRepository } from "../../repositories"; import { AbstractBootstrapper } from "../bootstrapper"; @@ -18,7 +19,15 @@ export class BootServiceProviders extends AbstractBootstrapper { for (const [name, serviceProvider] of serviceProviders.all()) { if (await serviceProvider.enableWhen()) { - await serviceProviders.boot(name); + try { + await serviceProviders.boot(name); + } catch (error) { + if (await serviceProvider.required()) { + throw new FailedServiceProviderBoot(serviceProvider.name(), error.message); + } + + serviceProviders.fail(serviceProvider.name()); + } } else { serviceProviders.defer(name); } diff --git a/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts b/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts index 5f4048a21d..3c1669ac98 100644 --- a/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts +++ b/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts @@ -30,7 +30,11 @@ export class RegisterServiceProviders extends AbstractBootstrapper { try { await serviceProviders.register(name); } catch (error) { - throw new FailedServiceProviderRegistration(serviceProvider.name(), error.message); + if (await serviceProvider.required()) { + throw new FailedServiceProviderRegistration(serviceProvider.name(), error.message); + } + + serviceProviders.fail(serviceProvider.name()); } } } @@ -54,14 +58,10 @@ export class RegisterServiceProviders extends AbstractBootstrapper { ); for (const dependency of dependencies) { - const { name, version, required, requiredWhen } = dependency; + const { name, version, required } = dependency; if (!serviceProviders.has(name)) { - let isRequired: boolean = !!required; - - if (requiredWhen) { - isRequired = await requiredWhen(); - } + const isRequired: boolean = typeof required === "function" ? await required() : !!required; const error: MissingDependency = new MissingDependency(serviceProvider.name(), name, isRequired); diff --git a/packages/core-kernel/src/contracts/core-kernel/application.ts b/packages/core-kernel/src/contracts/core-kernel/application.ts index 0474a3d7f4..c87adf45cf 100644 --- a/packages/core-kernel/src/contracts/core-kernel/application.ts +++ b/packages/core-kernel/src/contracts/core-kernel/application.ts @@ -200,8 +200,20 @@ export interface IApplication extends IContainer { * @interface IServiceProviderDependency */ export interface IServiceProviderDependency { + /** + * @type {string} + * @memberof IServiceProviderDependency + */ name: string; + + /** + * @type {string} + * @memberof IServiceProviderDependency + */ version?: string; - required?: boolean; - requiredWhen?: () => Promise; + + /** + * @memberof IServiceProviderDependency + */ + required?: boolean | (() => Promise); } diff --git a/packages/core-kernel/src/errors/kernel.ts b/packages/core-kernel/src/errors/kernel.ts index d84940d284..d46061cdd1 100644 --- a/packages/core-kernel/src/errors/kernel.ts +++ b/packages/core-kernel/src/errors/kernel.ts @@ -135,6 +135,22 @@ export class FailedServiceProviderRegistration extends KernelError { } } +/** + * @export + * @class FailedServiceProviderBoot + * @extends {KernelError} + */ +export class FailedServiceProviderBoot extends KernelError { + /** + * @param {string} name + * @param {string} error + * @memberof FailedServiceProviderBoot + */ + constructor(name: string, error: string) { + super(`Failed to boot "${name}": "${error}".`); + } +} + /** * @export * @class FailedDependencySatisfaction diff --git a/packages/core-kernel/src/support/service-provider.ts b/packages/core-kernel/src/support/service-provider.ts index 942126d9a4..bd4182ad21 100644 --- a/packages/core-kernel/src/support/service-provider.ts +++ b/packages/core-kernel/src/support/service-provider.ts @@ -131,6 +131,16 @@ export abstract class AbstractServiceProvider { return false; } + /** + * Terminate the process if the package is required. + * + * @returns {Promise} + * @memberof AbstractServiceProvider + */ + public async required(): Promise { + return true; + } + /** * @protected * @param {ConfigObject} opts diff --git a/packages/core-logger-pino/src/service-provider.ts b/packages/core-logger-pino/src/service-provider.ts index 05a1db16a3..d68b5b68cc 100644 --- a/packages/core-logger-pino/src/service-provider.ts +++ b/packages/core-logger-pino/src/service-provider.ts @@ -23,4 +23,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["log"]; } + + public async required(): Promise { + return true; + } } diff --git a/packages/core-logger-signale/src/service-provider.ts b/packages/core-logger-signale/src/service-provider.ts index 9daf6f67f9..1f17f0ede7 100644 --- a/packages/core-logger-signale/src/service-provider.ts +++ b/packages/core-logger-signale/src/service-provider.ts @@ -23,4 +23,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["log"]; } + + public async required(): Promise { + return true; + } } diff --git a/packages/core-logger-winston/src/service-provider.ts b/packages/core-logger-winston/src/service-provider.ts index e26f1131be..fc2a90ce49 100644 --- a/packages/core-logger-winston/src/service-provider.ts +++ b/packages/core-logger-winston/src/service-provider.ts @@ -23,4 +23,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["log"]; } + + public async required(): Promise { + return true; + } } diff --git a/packages/core-p2p/src/service-provider.ts b/packages/core-p2p/src/service-provider.ts index f00d34671b..74b8354d20 100644 --- a/packages/core-p2p/src/service-provider.ts +++ b/packages/core-p2p/src/service-provider.ts @@ -48,6 +48,10 @@ export class ServiceProvider extends Support.AbstractServiceProvider { return ["p2p"]; } + public async required(): Promise { + return true; + } + // @TODO: ioc private makePeerService(options): PeerService { const storage = new PeerStorage(); diff --git a/packages/core-transaction-pool/src/service-provider.ts b/packages/core-transaction-pool/src/service-provider.ts index dcf4fbb70a..da4bff88df 100644 --- a/packages/core-transaction-pool/src/service-provider.ts +++ b/packages/core-transaction-pool/src/service-provider.ts @@ -44,4 +44,8 @@ export class ServiceProvider extends Support.AbstractServiceProvider { public provides(): string[] { return ["transactionPool"]; } + + public async required(): Promise { + return true; + } }