Provide a way to tell when event handlers are finished
This lets us actually wait for disposal before a graceful exit.
This commit is contained in:
parent
396af23842
commit
8252c372af
@ -1,4 +1,10 @@
|
|||||||
import { Callback } from "./types"
|
import { logger } from "@coder/logger"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event emitter callback. Called with the emitted value and a promise that
|
||||||
|
* resolves when all emitters have finished.
|
||||||
|
*/
|
||||||
|
export type Callback<T, R = void | Promise<void>> = (t: T, p: Promise<void>) => R
|
||||||
|
|
||||||
export interface Disposable {
|
export interface Disposable {
|
||||||
dispose(): void
|
dispose(): void
|
||||||
@ -32,8 +38,21 @@ export class Emitter<T> {
|
|||||||
/**
|
/**
|
||||||
* Emit an event with a value.
|
* Emit an event with a value.
|
||||||
*/
|
*/
|
||||||
public emit(value: T): void {
|
public async emit(value: T): Promise<void> {
|
||||||
this.listeners.forEach((cb) => cb(value))
|
let resolve: () => void
|
||||||
|
const promise = new Promise<void>((r) => (resolve = r))
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
this.listeners.map(async (cb) => {
|
||||||
|
try {
|
||||||
|
await cb(value, promise)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error.message)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
resolve!()
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export type Callback<T, R = void> = (t: T) => R
|
|
@ -39,13 +39,14 @@ export class IpcMain {
|
|||||||
process.on("SIGTERM", () => this._onDispose.emit("SIGTERM"))
|
process.on("SIGTERM", () => this._onDispose.emit("SIGTERM"))
|
||||||
process.on("exit", () => this._onDispose.emit(undefined))
|
process.on("exit", () => this._onDispose.emit(undefined))
|
||||||
|
|
||||||
this.onDispose((signal) => {
|
this.onDispose((signal, wait) => {
|
||||||
// Remove listeners to avoid possibly triggering disposal again.
|
// Remove listeners to avoid possibly triggering disposal again.
|
||||||
process.removeAllListeners()
|
process.removeAllListeners()
|
||||||
|
|
||||||
// Let any other handlers run first then exit.
|
// Try waiting for other handlers run first then exit.
|
||||||
logger.debug(`${parentPid ? "inner process" : "wrapper"} ${process.pid} disposing`, field("code", signal))
|
logger.debug(`${parentPid ? "inner process" : "wrapper"} ${process.pid} disposing`, field("code", signal))
|
||||||
setTimeout(() => this.exit(0), 0)
|
wait.then(() => this.exit(0))
|
||||||
|
setTimeout(() => this.exit(0), 5000)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Kill the inner process if the parent dies. This is for the case where the
|
// Kill the inner process if the parent dies. This is for the case where the
|
||||||
|
Reference in New Issue
Block a user