diff --git a/packages/cardano-services/src/util/TypeormProvider/TypeormProvider.ts b/packages/cardano-services/src/util/TypeormProvider/TypeormProvider.ts index 08aed928fd2..a4dba7eeb28 100644 --- a/packages/cardano-services/src/util/TypeormProvider/TypeormProvider.ts +++ b/packages/cardano-services/src/util/TypeormProvider/TypeormProvider.ts @@ -1,10 +1,8 @@ -import { BehaviorSubject, Observable, Subscription, filter, firstValueFrom, tap } from 'rxjs'; -import { DataSource } from 'typeorm'; import { HealthCheckResponse, Provider } from '@cardano-sdk/core'; import { Logger } from 'ts-log'; +import { Observable, skip } from 'rxjs'; import { PgConnectionConfig } from '@cardano-sdk/projection-typeorm'; -import { RunnableModule, isNotNil } from '@cardano-sdk/util'; -import { createTypeormDataSource } from './util'; +import { TypeormService } from '../TypeormService'; export interface TypeormProviderDependencies { logger: Logger; @@ -12,61 +10,18 @@ export interface TypeormProviderDependencies { connectionConfig$: Observable; } -export abstract class TypeormProvider extends RunnableModule implements Provider { - #entities: Function[]; - #subscription: Subscription | undefined; - #connectionConfig$: Observable; - #dataSource$ = new BehaviorSubject(null); - +export abstract class TypeormProvider extends TypeormService implements Provider { health: HealthCheckResponse = { ok: false, reason: 'not started' }; constructor(name: string, { connectionConfig$, logger, entities }: TypeormProviderDependencies) { - super(name, logger); - this.#entities = entities; - this.#connectionConfig$ = connectionConfig$; - } - - #subscribeToDataSource() { - this.#subscription = createTypeormDataSource(this.#connectionConfig$, this.#entities, this.logger) - .pipe(tap(() => (this.health = { ok: true }))) - .subscribe((dataSource) => this.#dataSource$.next(dataSource)); - } - - #reset() { - this.#subscription?.unsubscribe(); - this.#subscription = undefined; - this.#dataSource$.value !== null && this.#dataSource$.next(null); - } - - onError(_: unknown) { - this.#reset(); - this.health = { ok: false, reason: 'Provider error' }; - this.#subscribeToDataSource(); - } - - async withDataSource(callback: (dataSource: DataSource) => Promise): Promise { - try { - return await callback(await firstValueFrom(this.#dataSource$.pipe(filter(isNotNil)))); - } catch (error) { - this.onError(error); - throw error; - } + super(name, { connectionConfig$, entities, logger }); + // We skip 1 to omit the initial null value of the subject + this.dataSource$.pipe(skip(1)).subscribe((dataSource) => { + this.health = dataSource ? { ok: true } : { ok: false, reason: 'Provider error' }; + }); } async healthCheck(): Promise { return this.health; } - - async initializeImpl() { - return Promise.resolve(); - } - - async startImpl() { - this.#subscribeToDataSource(); - } - - async shutdownImpl() { - this.#reset(); - this.#dataSource$.complete(); - } } diff --git a/packages/cardano-services/src/util/TypeormProvider/index.ts b/packages/cardano-services/src/util/TypeormProvider/index.ts index 752b0680144..705ad9dd4d9 100644 --- a/packages/cardano-services/src/util/TypeormProvider/index.ts +++ b/packages/cardano-services/src/util/TypeormProvider/index.ts @@ -1,2 +1 @@ export * from './TypeormProvider'; -export * from './util'; diff --git a/packages/cardano-services/src/util/TypeormService/TypeormService.ts b/packages/cardano-services/src/util/TypeormService/TypeormService.ts index 901ae3dc354..52f7daede54 100644 --- a/packages/cardano-services/src/util/TypeormService/TypeormService.ts +++ b/packages/cardano-services/src/util/TypeormService/TypeormService.ts @@ -3,16 +3,22 @@ import { DataSource } from 'typeorm'; import { Logger } from 'ts-log'; import { PgConnectionConfig } from '@cardano-sdk/projection-typeorm'; import { RunnableModule, isNotNil } from '@cardano-sdk/util'; -import { TypeormProviderDependencies, createTypeormDataSource } from '../TypeormProvider'; +import { createTypeormDataSource } from '../createTypeormDataSource'; -export class TypeormService extends RunnableModule { +interface TypeormServiceDependencies { + logger: Logger; + entities: Function[]; + connectionConfig$: Observable; +} + +export abstract class TypeormService extends RunnableModule { #entities: Function[]; #connectionConfig$: Observable; logger: Logger; - #dataSource$ = new BehaviorSubject(null); + protected dataSource$ = new BehaviorSubject(null); #subscription: Subscription | undefined; - constructor(name: string, { connectionConfig$, logger, entities }: TypeormProviderDependencies) { + constructor(name: string, { connectionConfig$, logger, entities }: TypeormServiceDependencies) { super(name, logger); this.#entities = entities; this.#connectionConfig$ = connectionConfig$; @@ -20,14 +26,14 @@ export class TypeormService extends RunnableModule { #subscribeToDataSource() { this.#subscription = createTypeormDataSource(this.#connectionConfig$, this.#entities, this.logger).subscribe( - (dataSource) => this.#dataSource$.next(dataSource) + (dataSource) => this.dataSource$.next(dataSource) ); } #reset() { this.#subscription?.unsubscribe(); this.#subscription = undefined; - this.#dataSource$.value !== null && this.#dataSource$.next(null); + this.dataSource$.value !== null && this.dataSource$.next(null); } onError(_: unknown) { @@ -37,7 +43,7 @@ export class TypeormService extends RunnableModule { async withDataSource(callback: (dataSource: DataSource) => Promise): Promise { try { - return await callback(await firstValueFrom(this.#dataSource$.pipe(filter(isNotNil)))); + return await callback(await firstValueFrom(this.dataSource$.pipe(filter(isNotNil)))); } catch (error) { this.onError(error); throw error; @@ -54,6 +60,6 @@ export class TypeormService extends RunnableModule { async shutdownImpl() { this.#reset(); - this.#dataSource$.complete(); + this.dataSource$.complete(); } } diff --git a/packages/cardano-services/src/util/TypeormProvider/util.ts b/packages/cardano-services/src/util/createTypeormDataSource.ts similarity index 100% rename from packages/cardano-services/src/util/TypeormProvider/util.ts rename to packages/cardano-services/src/util/createTypeormDataSource.ts