From 4f43f9fa542ca4442e99ffc55e1702e1ea32bda7 Mon Sep 17 00:00:00 2001 From: Ben Allfree Date: Sun, 18 Jun 2023 05:50:28 -0700 Subject: [PATCH] enh: cleanupManager async cleanups and singleton shutdown --- packages/common/src/CleanupManager.ts | 43 ++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/packages/common/src/CleanupManager.ts b/packages/common/src/CleanupManager.ts index 8cbf3a4f..5111b42c 100644 --- a/packages/common/src/CleanupManager.ts +++ b/packages/common/src/CleanupManager.ts @@ -1,20 +1,49 @@ -import { map } from '@s-libs/micro-dash' +import { reduce, values } from '@s-libs/micro-dash' +import { nanoid } from 'nanoid' +import { logger } from './Logger' -export type CleanupFunc = () => any -export const createCleanupManager = () => { +export type CleanupFunc = () => Promise | void +type CleanupRec = { + cleanup: CleanupFunc + priority: number +} +export const CLEANUP_DEFAULT_PRIORITY = 10 + +export const createCleanupManager = (slug?: string) => { + const _slug = slug || nanoid() + const { error, warn, dbg } = logger().create(`cleanupManager:${_slug}`) let i = 0 - const cleanups: any = {} - const add = (cb: CleanupFunc) => { + const cleanups: { [_: number]: CleanupRec } = {} + const add = (cb: CleanupFunc, priority = CLEANUP_DEFAULT_PRIORITY) => { const idx = i++ const cleanup = async () => { await cb() delete cleanups[idx] } - cleanups[idx] = cleanup + cleanups[idx] = { cleanup, priority } return cleanup } - const shutdown = () => Promise.all(map(cleanups, (v) => v())) + let _shutdownP: Promise | undefined = undefined + const shutdown: () => Promise = () => { + if (_shutdownP) return _shutdownP + const _cleanupFuncs = values(cleanups) + .sort((a, b) => a.priority - b.priority) + .map((v) => v.cleanup) + _shutdownP = reduce( + _cleanupFuncs, + (c, v) => { + return c.then(() => v()) + }, + Promise.resolve() + ).catch((e) => { + error( + `Cleanup functions are failing. This should never happen, check all cleanup functions to make sure they are trapping their exceptions.` + ) + throw e + }) + return _shutdownP + } return { add, shutdown } }