Skip to content

Commit

Permalink
heart.ts: Fix leak when server closes
Browse files Browse the repository at this point in the history
This had me very confused for quite a while until I did a binary search
inspection on route/index.ts. Only with the heart.beat line commented
out did my tests pass without leaking.

They weren't leaking fds but just this heartbeat timer and node of
course prints just fds that are active when it detects some sort of leak
I guess and that made the whole thing very confusing. These fds are not
leaked and will close when node's event loop detects there are no more
callbacks to run.

no of handles 3

tcp stream {
  fd: 20,
  readable: false,
  writable: true,
  address: {},
  serverAddr: null
}

tcp stream {
  fd: 22,
  readable: false,
  writable: true,
  address: {},
  serverAddr: null
}

tcp stream {
  fd: 23,
  readable: true,
  writable: false,
  address: {},
  serverAddr: null
}

It kept printing the above text again and again for 60s and then the
test binary times out I think. I'm not sure if it was node printing the
stuff above or if it was a mocha thing. But it was really confusing...

cc @code-asher for thoughts on what was going on.

edit: It was the leaked-handles import in socket.test.ts!!!
Not sure if we should keep it, this was really confusing and misleading.
  • Loading branch information
nhooyr committed Jan 20, 2021
1 parent 5c06646 commit c32d8b1
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/node/heart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,13 @@ export class Heart {
})
}, this.heartbeatInterval)
}

/**
* Call to clear any heartbeatTimer for shutdown.
*/
public dispose(): void {
if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer)
}
}
}
3 changes: 3 additions & 0 deletions src/node/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export const register = async (
})
})
})
server.on("close", () => {
heart.dispose()
})

app.disable("x-powered-by")
wsApp.disable("x-powered-by")
Expand Down
2 changes: 2 additions & 0 deletions test/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export async function setup(
argv: string[],
configFile?: string,
): Promise<[express.Application, express.Application, httpserver.HttpServer, DefaultedArgs]> {
argv = ["--bind-addr=localhost:0", ...argv]

const cliArgs = parse(argv)
const configArgs = parseConfigFile(configFile || "", "test/integration.ts")
const args = await setDefaults(cliArgs, configArgs)
Expand Down

0 comments on commit c32d8b1

Please sign in to comment.