Skip to content

Commit 822af7a

Browse files
committedOct 26, 2024
Rework handling of reentrancy in NodeStreamLink.
1 parent d378470 commit 822af7a

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed
 

‎src/cxxrtl/link.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -79,26 +79,32 @@ export class NodeStreamLink implements ILink {
7979
this.recvBuffer.splice(0, this.recvBuffer.length, rest.at(-1)!);
8080
}
8181

82-
// Second, process the packets. This involves steps that may throw errors, so we catch
83-
// them all. Also, the stream is paused so that this event handler isn't re-entered despite
84-
// using `await` here.
85-
this.stream.pause();
82+
// Second, convert the packet text to JSON. This can throw errors e.g. if there is foreign
83+
// data injected between server replies, or the server is malfunctioning. In that case,
84+
// stop processing input.
85+
const packets: proto.ServerPacket[] = [];
8686
for (const packetText of packetTexts) {
8787
try {
88-
const packet = JSON.parse(packetText) as proto.ServerPacket;
88+
packets.push(JSON.parse(packetText) as proto.ServerPacket);
89+
} catch (error) {
90+
console.error('malformed JSON: ', packetText);
91+
this.stream.pause();
92+
return;
93+
}
94+
}
95+
96+
// Finally, run the handler for each of the packets. If the handler blocks, don't wait for
97+
// its completion, but run the next handler anyway; this is because a handler can send
98+
// another client packet, causing `onStreamData` to be re-entered, anyway.
99+
for (const packet of packets) {
100+
(async (packet: proto.ServerPacket) => {
89101
try {
90102
await this.onRecv(packet);
91-
this.stream.resume();
92103
} catch (error) {
93104
console.error('uncaught error in onRecv', error);
94-
return; // leave paused
95105
}
96-
} catch (error) {
97-
console.error('malformed JSON: ', packetText);
98-
return; // leave paused
99-
}
106+
})(packet);
100107
}
101-
this.stream.resume();
102108
}
103109

104110
private async onStreamEnd(): Promise<void> {

0 commit comments

Comments
 (0)
Please sign in to comment.