enh: cleanupManager async cleanups and singleton shutdown

This commit is contained in:
Ben Allfree 2023-06-18 05:50:28 -07:00
parent f5f19d3f78
commit 4f43f9fa54

View File

@ -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 type CleanupFunc = () => Promise<void> | void
export const createCleanupManager = () => { 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 let i = 0
const cleanups: any = {} const cleanups: { [_: number]: CleanupRec } = {}
const add = (cb: CleanupFunc) => { const add = (cb: CleanupFunc, priority = CLEANUP_DEFAULT_PRIORITY) => {
const idx = i++ const idx = i++
const cleanup = async () => { const cleanup = async () => {
await cb() await cb()
delete cleanups[idx] delete cleanups[idx]
} }
cleanups[idx] = cleanup cleanups[idx] = { cleanup, priority }
return cleanup return cleanup
} }
const shutdown = () => Promise.all(map(cleanups, (v) => v())) let _shutdownP: Promise<void> | undefined = undefined
const shutdown: () => Promise<void> = () => {
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 } return { add, shutdown }
} }