|
10 | 10 | */
|
11 | 11 |
|
12 | 12 | import stream from "stream";
|
13 |
| -import { encodeMessage } from "../io/encoder"; |
14 | 13 | import { streamDecoder } from "../io/decoder";
|
15 | 14 | import { Connection, RestateStreamConsumer } from "./connection";
|
16 | 15 | import { Message } from "../types/types";
|
17 | 16 | import { rlog } from "../utils/logger";
|
18 | 17 | import { finished } from "stream/promises";
|
| 18 | +import { BufferedConnection } from "./buffered_connection"; |
19 | 19 |
|
20 | 20 | // utility promise, for cases where we want to save allocation of an extra promise
|
21 | 21 | const RESOLVED: Promise<void> = Promise.resolve();
|
@@ -55,19 +55,25 @@ export class RestateHttp2Connection implements Connection {
|
55 | 55 | // input as decoded messages
|
56 | 56 | private readonly sdkInput: stream.Readable;
|
57 | 57 |
|
58 |
| - // output as encoded bytes. we convert manually, not as transforms, |
59 |
| - // to skip a layer of stream indirection |
60 |
| - private readonly sdkOutput: stream.Writable; |
61 |
| - |
62 | 58 | // consumer handling
|
63 | 59 | private currentConsumer: RestateStreamConsumer | null = null;
|
64 | 60 | private inputBuffer: Message[] = [];
|
65 | 61 | private consumerError?: Error;
|
66 | 62 | private consumerInputClosed = false;
|
67 | 63 |
|
| 64 | + private outputBuffer: BufferedConnection; |
| 65 | + |
68 | 66 | constructor(private readonly rawStream: stream.Duplex) {
|
69 | 67 | this.sdkInput = rawStream.pipe(streamDecoder());
|
70 |
| - this.sdkOutput = rawStream; |
| 68 | + |
| 69 | + this.outputBuffer = new BufferedConnection((buffer) => { |
| 70 | + const hasMoreCapacity = rawStream.write(buffer); |
| 71 | + if (hasMoreCapacity) { |
| 72 | + return RESOLVED; |
| 73 | + } else { |
| 74 | + return new Promise((resolve) => rawStream.once("drain", resolve)); |
| 75 | + } |
| 76 | + }); |
71 | 77 |
|
72 | 78 | // remember and forward messages
|
73 | 79 | this.sdkInput.on("data", (m: Message) => {
|
@@ -201,23 +207,16 @@ export class RestateHttp2Connection implements Connection {
|
201 | 207 | * capacity again, so that at least the operations that await results will respect backpressure.
|
202 | 208 | */
|
203 | 209 | public send(msg: Message): Promise<void> {
|
204 |
| - const encodedMessage: Uint8Array = encodeMessage(msg); |
205 |
| - |
206 |
| - const hasMoreCapacity = this.sdkOutput.write(encodedMessage); |
207 |
| - if (hasMoreCapacity) { |
208 |
| - return RESOLVED; |
209 |
| - } |
210 |
| - |
211 |
| - return new Promise((resolve) => { |
212 |
| - this.sdkOutput.once("drain", resolve); |
213 |
| - }); |
| 210 | + return this.outputBuffer.send(msg); |
214 | 211 | }
|
215 | 212 |
|
216 | 213 | /**
|
217 | 214 | * Ends the stream, awaiting pending writes.
|
218 | 215 | */
|
219 | 216 | public async end(): Promise<void> {
|
220 |
| - this.sdkOutput.end(); |
| 217 | + await this.outputBuffer.end(); |
| 218 | + |
| 219 | + this.rawStream.end(); |
221 | 220 |
|
222 | 221 | const options = {
|
223 | 222 | error: true,
|
|
0 commit comments