backend-defaults: fix SQLite shutdown hanging

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-10-10 12:20:25 +02:00
parent f7bc5a2a5f
commit d7b44f0b3c
3 changed files with 51 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-defaults': patch
---
Fix for backend shutdown hanging during local development due to SQLite connection shutdown never resolving.
@@ -182,7 +182,9 @@ describe('DatabaseManagerImpl', () => {
const rootLifecycle = { addShutdownHook: jest.fn() } as unknown as any;
const destroy = jest.fn();
const connector1 = {
getClient: jest.fn().mockResolvedValue({ destroy }),
getClient: jest
.fn()
.mockResolvedValue({ destroy, client: { config: 'pg' } }),
} satisfies Connector;
const impl = new DatabaseManagerImpl(
new ConfigReader({
@@ -207,4 +209,44 @@ describe('DatabaseManagerImpl', () => {
// Then the destroy method should have been called on the resolved client
expect(destroy).toHaveBeenCalled();
});
it('does not attempt to destroy connection when using SQLite', async () => {
// Same us the previous test, but with SQLite
const rootLifecycle = { addShutdownHook: jest.fn() } as unknown as any;
// Make sure we're actually checking the client, since we're ignoring errors
const getConfig = jest.fn().mockReturnValue('sqlite3');
const destroy = jest.fn();
const connector1 = {
getClient: jest.fn().mockResolvedValue({
destroy,
client: {
get config() {
return getConfig();
},
},
}),
} satisfies Connector;
const impl = new DatabaseManagerImpl(
new ConfigReader({
client: 'pg',
}),
{
pg: connector1,
},
{ rootLifecycle },
);
expect(rootLifecycle.addShutdownHook).toHaveBeenCalled();
const shutdownHook = rootLifecycle.addShutdownHook.mock.calls[0][0];
await impl.forPlugin('plugin1', deps).getClient();
await shutdownHook();
// Destroy should not have been called, but we should have read the config
expect(destroy).not.toHaveBeenCalled();
expect(getConfig).toHaveBeenCalled();
});
});
@@ -117,6 +117,9 @@ export class DatabaseManagerImpl {
const connection = await this.databaseCache.get(pluginId);
if (connection) {
if (connection.client.config.includes('sqlite3')) {
return; // sqlite3 does not support destroy, it hangs
}
await connection.destroy().catch((error: unknown) => {
deps?.logger?.error(
`Problem closing database connection for ${pluginId}: ${stringifyError(