Improve bridge batching logic

Fixes #132.
This commit is contained in:
Sophie Alpert
2019-04-10 16:31:11 -07:00
parent 40469a190e
commit 7c13ea2f2b
+27 -23
View File
@@ -13,7 +13,6 @@ type Message = {|
export default class Bridge extends EventEmitter {
_messageQueue: Array<any> = [];
_time: number | null = null;
_timeoutID: TimeoutID | null = null;
_wall: Wall;
@@ -28,34 +27,39 @@ export default class Bridge extends EventEmitter {
}
send(event: string, payload: any, transferable?: Array<any>) {
const time = this._time;
// When we receive a message:
// - we add it to our queue of messages to be sent
// - if there hasn't been a message recently, we set a timer for 0 ms in
// the future, allowing all messages created in the same tick to be sent
// together
// - if there *has* been a message flushed in the last BATCH_DURATION ms
// (or we're waiting for our setTimeout-0 to fire), then _timeoutID will
// be set, and we'll simply add to the queue and wait for that
if (time === null) {
this._wall.send(event, payload, transferable);
this._time = Date.now();
} else {
this._messageQueue.push(event, payload, transferable);
const now = Date.now();
if (now - time > BATCH_DURATION) {
this._flush();
} else {
this._timeoutID = setTimeout(this._flush, BATCH_DURATION);
}
this._messageQueue.push(event, payload, transferable);
if (!this._timeoutID) {
this._timeoutID = setTimeout(this._flush, 0);
}
}
_flush = () => {
while (this._messageQueue.length) {
this._wall.send.apply(this._wall, this._messageQueue.splice(0, 3));
}
clearTimeout(this._timeoutID);
this._timeoutID = null;
if (this._timeoutID !== null) {
clearTimeout(this._timeoutID);
this._timeoutID = null;
}
if (this._messageQueue.length) {
for (let i = 0; i < this._messageQueue.length; i += 3) {
this._wall.send(
this._messageQueue[i],
this._messageQueue[i + 1],
this._messageQueue[i + 2],
);
}
this._messageQueue.length = 0;
this._messageQueue = [];
this._time = null;
// Check again for queued messages in BATCH_DURATION ms. This will keep
// flushing in a loop as long as messages continue to be added. Once no
// more are, the timer expires.
this._timeoutID = setTimeout(this._flush, BATCH_DURATION);
}
};
}