parent
1ab6a5219d
commit
4e84e698cd
@ -0,0 +1,57 @@ |
|||||||
|
import {EventEmitter} from 'events'; |
||||||
|
import { StringDecoder } from 'string_decoder'; |
||||||
|
// Max duration to batch session data before sending it to the renderer process.
|
||||||
|
const BATCH_DURATION_MS = 16; |
||||||
|
|
||||||
|
// Max size of a session data batch. Note that this value can be exceeded by ~4k
|
||||||
|
// (chunk sizes seem to be 4k at the most)
|
||||||
|
const BATCH_MAX_SIZE = 200 * 1024; |
||||||
|
|
||||||
|
// Data coming from the pty is sent to the renderer process for further
|
||||||
|
// vt parsing and rendering. This class batches data to minimize the number of
|
||||||
|
// IPC calls. It also reduces GC pressure and CPU cost: each chunk is prefixed
|
||||||
|
// with the window ID which is then stripped on the renderer process and this
|
||||||
|
// overhead is reduced with batching.
|
||||||
|
export class DataBatcher extends EventEmitter { |
||||||
|
uid: number; |
||||||
|
decoder: StringDecoder; |
||||||
|
data!: string; |
||||||
|
timeout!: NodeJS.Timeout | null; |
||||||
|
constructor(uid: number) { |
||||||
|
super(); |
||||||
|
this.uid = uid; |
||||||
|
this.decoder = new StringDecoder('utf8'); |
||||||
|
|
||||||
|
this.reset(); |
||||||
|
} |
||||||
|
|
||||||
|
reset() { |
||||||
|
this.data = ''; |
||||||
|
this.timeout = null; |
||||||
|
} |
||||||
|
|
||||||
|
write(chunk: Buffer) { |
||||||
|
if (this.data.length + chunk.length >= BATCH_MAX_SIZE) { |
||||||
|
// We've reached the max batch size. Flush it and start another one
|
||||||
|
if (this.timeout) { |
||||||
|
clearTimeout(this.timeout); |
||||||
|
this.timeout = null; |
||||||
|
} |
||||||
|
this.flush(); |
||||||
|
} |
||||||
|
|
||||||
|
this.data += this.decoder.write(chunk); |
||||||
|
|
||||||
|
if (!this.timeout) { |
||||||
|
this.timeout = setTimeout(() => this.flush(), BATCH_DURATION_MS); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
flush() { |
||||||
|
// Reset before emitting to allow for potential reentrancy
|
||||||
|
const data = this.data; |
||||||
|
this.reset(); |
||||||
|
|
||||||
|
this.emit('flush', data, this.uid); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue