Refactor DB Manager shutdown to be private
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
@@ -19,6 +19,8 @@ import {
|
||||
LifecycleService,
|
||||
LoggerService,
|
||||
RootConfigService,
|
||||
RootLifecycleService,
|
||||
RootLoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { stringifyError } from '@backstage/errors';
|
||||
@@ -42,6 +44,8 @@ function pluginPath(pluginId: string): string {
|
||||
*/
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: DatabaseService['migrations'];
|
||||
rootLogger?: RootLoggerService;
|
||||
rootLifecycle?: RootLifecycleService;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -53,7 +57,15 @@ export class DatabaseManagerImpl {
|
||||
private readonly connectors: Record<string, Connector>,
|
||||
private readonly options?: DatabaseManagerOptions,
|
||||
private readonly databaseCache: Map<string, Promise<Knex>> = new Map(),
|
||||
) {}
|
||||
) {
|
||||
// If a rootLifecycle service was provided, register a shutdown hook to
|
||||
// clean up any database connections.
|
||||
if (options?.rootLifecycle !== undefined) {
|
||||
options.rootLifecycle.addShutdownHook(async () => {
|
||||
await this.shutdown({ logger: options.rootLogger });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PluginDatabaseManager for consumption by plugins.
|
||||
@@ -90,16 +102,16 @@ export class DatabaseManagerImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called during shutdown to destroy all known connections.
|
||||
* Destroys all known connections.
|
||||
*/
|
||||
async shutdown(deps: { logger: LoggerService }): Promise<void> {
|
||||
private async shutdown(deps?: { logger?: LoggerService }): Promise<void> {
|
||||
const pluginIds = Array.from(this.databaseCache.keys());
|
||||
await Promise.allSettled(
|
||||
pluginIds.map(async pluginId => {
|
||||
const connection = await this.databaseCache.get(pluginId);
|
||||
if (connection) {
|
||||
await connection.destroy().catch((error: unknown) => {
|
||||
deps.logger.error(
|
||||
deps?.logger?.error(
|
||||
`Problem closing database connection for ${pluginId}: ${stringifyError(
|
||||
error,
|
||||
)}`,
|
||||
@@ -257,11 +269,4 @@ export class DatabaseManager {
|
||||
): PluginDatabaseManager {
|
||||
return this.impl.forPlugin(pluginId, deps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called during shutdown to destroy all known connections.
|
||||
*/
|
||||
async shutdown(deps: { logger: LoggerService }): Promise<void> {
|
||||
return this.impl.shutdown(deps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,21 +41,16 @@ export const databaseServiceFactory = createServiceFactory({
|
||||
rootLogger: coreServices.rootLogger,
|
||||
},
|
||||
async createRootContext({ config, rootLifecycle, rootLogger }) {
|
||||
const databaseManager = config.getOptional('backend.database')
|
||||
? DatabaseManager.fromConfig(config)
|
||||
return config.getOptional('backend.database')
|
||||
? DatabaseManager.fromConfig(config, { rootLifecycle, rootLogger })
|
||||
: DatabaseManager.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
database: { client: 'better-sqlite3', connection: ':memory:' },
|
||||
},
|
||||
}),
|
||||
{ rootLifecycle, rootLogger },
|
||||
);
|
||||
|
||||
rootLifecycle.addShutdownHook(async () => {
|
||||
await databaseManager.shutdown({ logger: rootLogger });
|
||||
});
|
||||
|
||||
return databaseManager;
|
||||
},
|
||||
async factory({ pluginMetadata, lifecycle, logger }, databaseManager) {
|
||||
return databaseManager.forPlugin(pluginMetadata.getId(), {
|
||||
|
||||
Reference in New Issue
Block a user