Improve bridge batching logic
Fixes #132.
Sophie Alpert committed
Apr 10, 2019 at 16:31 UTC
7c13ea2f2b9aa11859c44f01dfeef29d402b276c
1 file changed
+28
-24
src/bridge.js
+28
-24
@@ -13,7 +13,6 @@ type Message = {|
13
14
export default class Bridge extends EventEmitter {
15
_messageQueue: Array<any> = [];
16
- _time: number | null = null;
16
_timeoutID: TimeoutID | null = null;
17
_wall: Wall;
18
@@ -28,34 +27,39 @@ export default class Bridge extends EventEmitter {
27
}
28
29
send(event: string, payload: any, transferable?: Array<any>) {
31
- const time = this._time;
32
-
33
- if (time === null) {
34
- this._wall.send(event, payload, transferable);
35
- this._time = Date.now();
36
- } else {
37
- this._messageQueue.push(event, payload, transferable);
38
-
39
- const now = Date.now();
40
- if (now - time > BATCH_DURATION) {
41
- this._flush();
42
- } else {
43
- this._timeoutID = setTimeout(this._flush, BATCH_DURATION);
44
- }
30
+ // When we receive a message:
31
+ // - we add it to our queue of messages to be sent
32
+ // - if there hasn't been a message recently, we set a timer for 0 ms in
33
+ // the future, allowing all messages created in the same tick to be sent
34
+ // together
35
+ // - if there *has* been a message flushed in the last BATCH_DURATION ms
36
+ // (or we're waiting for our setTimeout-0 to fire), then _timeoutID will
37
+ // be set, and we'll simply add to the queue and wait for that
38
+
39
+ this._messageQueue.push(event, payload, transferable);
40
+ if (!this._timeoutID) {
41
+ this._timeoutID = setTimeout(this._flush, 0);
42
}
43
}
44
45
_flush = () => {
49
- while (this._messageQueue.length) {
50
- this._wall.send.apply(this._wall, this._messageQueue.splice(0, 3));
51
- }
46
+ clearTimeout(this._timeoutID);
47
+ this._timeoutID = null;
48
53
- if (this._timeoutID !== null) {
54
- clearTimeout(this._timeoutID);
55
- this._timeoutID = null;
56
- }
49
+ if (this._messageQueue.length) {
50
+ for (let i = 0; i < this._messageQueue.length; i += 3) {
51
+ this._wall.send(
52
+ this._messageQueue[i],
53
+ this._messageQueue[i + 1],
54
+ this._messageQueue[i + 2],
55
+ );
56
+ }
57
+ this._messageQueue.length = 0;
58
58
- this._messageQueue = [];
59
- this._time = null;
59
+ // Check again for queued messages in BATCH_DURATION ms. This will keep
60
+ // flushing in a loop as long as messages continue to be added. Once no
61
+ // more are, the timer expires.
62
+ this._timeoutID = setTimeout(this._flush, BATCH_DURATION);
63
+ }
64
};
65
}