diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-04-29 01:08:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-29 01:08:02 +0200 |
commit | 640f6878f61204bf7211cd9f0750b3ab6dee57b8 (patch) | |
tree | 0339398a002ae8331cae1007ffb99dde701999b1 /cli/js | |
parent | 6fd754fba06ab3e3c4447fe118e780aa5040a419 (diff) |
refactor: Deno.listener closes when breaking out of async iterator (#4976)
Diffstat (limited to 'cli/js')
-rw-r--r-- | cli/js/net.ts | 31 | ||||
-rw-r--r-- | cli/js/tests/net_test.ts | 36 |
2 files changed, 56 insertions, 11 deletions
diff --git a/cli/js/net.ts b/cli/js/net.ts index 962c78a5b..b06a4189a 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -61,21 +61,30 @@ export class ListenerImpl implements Listener { return new ConnImpl(res.rid, res.remoteAddr, res.localAddr); } + async next(): Promise<IteratorResult<Conn>> { + let conn: Conn; + try { + conn = await this.accept(); + } catch (error) { + if (error instanceof errors.BadResource) { + return { value: undefined, done: true }; + } + throw error; + } + return { value: conn!, done: false }; + } + + return(value?: Conn): Promise<IteratorResult<Conn>> { + this.close(); + return Promise.resolve({ value, done: true }); + } + close(): void { close(this.rid); } - async *[Symbol.asyncIterator](): AsyncIterableIterator<Conn> { - while (true) { - try { - yield await this.accept(); - } catch (error) { - if (error instanceof errors.BadResource) { - break; - } - throw error; - } - } + [Symbol.asyncIterator](): AsyncIterableIterator<Conn> { + return this; } } diff --git a/cli/js/tests/net_test.ts b/cli/js/tests/net_test.ts index f5c1f7abd..64edf34ea 100644 --- a/cli/js/tests/net_test.ts +++ b/cli/js/tests/net_test.ts @@ -287,6 +287,42 @@ unitTest( unitTest( { perms: { net: true } }, + async function netTcpListenIteratorBreakClosesResource(): Promise<void> { + const promise = createResolvable(); + + async function iterate(listener: Deno.Listener): Promise<void> { + let i = 0; + + for await (const conn of listener) { + conn.close(); + i++; + + if (i > 1) { + break; + } + } + + promise.resolve(); + } + + const addr = { hostname: "127.0.0.1", port: 8888 }; + const listener = Deno.listen(addr); + iterate(listener); + + await new Promise((resolve: () => void, _) => { + setTimeout(resolve, 100); + }); + const conn1 = await Deno.connect(addr); + conn1.close(); + const conn2 = await Deno.connect(addr); + conn2.close(); + + await promise; + } +); + +unitTest( + { perms: { net: true } }, async function netTcpListenCloseWhileIterating(): Promise<void> { const listener = Deno.listen({ port: 8000 }); const nextWhileClosing = listener[Symbol.asyncIterator]().next(); |