0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

refactor: Deno.listener closes when breaking out of async iterator (#4976)

This commit is contained in:
Bartek Iwańczuk 2020-04-29 01:08:02 +02:00 committed by GitHub
parent 6fd754fba0
commit 640f6878f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 11 deletions

View file

@ -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;
}
}

View file

@ -285,6 +285,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> {