From c6b2ec89fec1cd49fb2aeed2214a94b9ff1fe8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Str=C3=B6mberg?= Date: Mon, 18 Sep 2023 10:39:53 +0200 Subject: [PATCH] Wrap nRepl client close in a promise Poor (dumb) man's way to wait for `close` messages to have been sent before destroying the socket. * Fixes #2301 --- src/connector.ts | 4 ++-- src/nrepl/index.ts | 22 ++++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/connector.ts b/src/connector.ts index 8957d2dab..365002c70 100644 --- a/src/connector.ts +++ b/src/connector.ts @@ -68,7 +68,7 @@ async function connectToHost(hostname: string, port: number, connectSequence: Re if (nClient) { nClient['silent'] = true; - nClient.close(); + await nClient.close(); } let cljSession: NReplSession; @@ -863,7 +863,7 @@ export default { } else { // the connection may be ended before // the REPL client was connected. - nClient.close(); + void nClient.close(); } liveShareSupport.didDisconnectRepl(); nClient = undefined; diff --git a/src/nrepl/index.ts b/src/nrepl/index.ts index 8d685fea9..8909faaaa 100644 --- a/src/nrepl/index.ts +++ b/src/nrepl/index.ts @@ -111,14 +111,20 @@ export class NReplClient { log(data, Direction.ClientToServer); } - close() { - for (const id in this.sessions) { - this.sessions[id].close(); - } - // TODO: Figure out a way to know when the socket can be destroyed without an error. - setTimeout(() => { - this.disconnect(); - }, 1000); + async close() { + return new Promise((resolve, _reject) => { + for (const id in this.sessions) { + this.sessions[id].close(); + } + // TODO: We probably need to make the whole disconnect process awaitable + // So that we do not destroy the socket before we have sent the `close` message + // This setTimeout caused https://github.com/BetterThanTomorrow/calva/issues/2301 + // For now wrapped in a promise... + setTimeout(() => { + this.disconnect(); + resolve(this); + }, 1000); + }); } disconnect() {