Skip to content

Commit 7779039

Browse files
committed
Provide a way to tell when event handlers are finished
This lets us actually wait for disposal before a graceful exit.
1 parent 396af23 commit 7779039

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

src/common/emitter.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { Callback } from "./types"
1+
import { logger } from "@coder/logger"
2+
3+
/**
4+
* Event emitter callback. Called with the emitted value and a promise that
5+
* resolves when all emitters have finished.
6+
*/
7+
export type Callback<T, R = void | Promise<void>> = (t: T, p: Promise<void[]>) => R
28

39
export interface Disposable {
410
dispose(): void
@@ -32,8 +38,17 @@ export class Emitter<T> {
3238
/**
3339
* Emit an event with a value.
3440
*/
35-
public emit(value: T): void {
36-
this.listeners.forEach((cb) => cb(value))
41+
public emit(value: T): Promise<void[]> {
42+
const promise = Promise.all(
43+
this.listeners.map(async (cb) => {
44+
try {
45+
await cb(value, promise)
46+
} catch (error) {
47+
logger.error(error.message)
48+
}
49+
}),
50+
)
51+
return promise
3752
}
3853

3954
public dispose(): void {

src/common/types.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/node/wrapper.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ export class IpcMain {
3939
process.on("SIGTERM", () => this._onDispose.emit("SIGTERM"))
4040
process.on("exit", () => this._onDispose.emit(undefined))
4141

42-
this.onDispose((signal) => {
42+
this.onDispose((signal, wait) => {
4343
// Remove listeners to avoid possibly triggering disposal again.
4444
process.removeAllListeners()
4545

46-
// Let any other handlers run first then exit.
46+
// Try waiting for other handlers run first then exit.
4747
logger.debug(`${parentPid ? "inner process" : "wrapper"} ${process.pid} disposing`, field("code", signal))
48-
setTimeout(() => this.exit(0), 0)
48+
wait.then(() => this.exit(0))
49+
setTimeout(() => this.exit(0), 5000)
4950
})
5051

5152
// Kill the inner process if the parent dies. This is for the case where the

0 commit comments

Comments
 (0)