Skip to content

Commit

Permalink
throttle presence updates over http
Browse files Browse the repository at this point in the history
  • Loading branch information
a-type committed Jun 20, 2024
1 parent 542c728 commit d876471
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/light-plants-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@verdant-web/common': patch
'@verdant-web/store': patch
---

Throttle presence updates over http sync to reduce http requests
26 changes: 26 additions & 0 deletions packages/common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,29 @@ export function debounce<T extends (...args: any[]) => any>(
timeout = setTimeout(() => fn.apply(context, args), wait);
} as any;
}

export function throttle<T extends (...args: any[]) => any>(
fn: T,
wait: number,
): T {
let lastTime = 0;

// invoke once for the last call
let trailingTimeout: any;

return function (this: any, ...args: any[]) {
const context = this;
const now = Date.now();
if (now - lastTime >= wait) {
lastTime = now;
fn.apply(context, args);
clearTimeout(trailingTimeout);
} else {
clearTimeout(trailingTimeout);
trailingTimeout = setTimeout(() => {
lastTime = now;
fn.apply(context, args);
}, wait);
}
} as any;
}
10 changes: 10 additions & 0 deletions packages/store/src/sync/PushPullSync.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {
ClientMessage,
EventSubscriber,
PresenceUpdateMessage,
ServerMessage,
VerdantErrorCode,
debounce,
isVerdantErrorResponse,
throttle,
} from '@verdant-web/common';
import { Metadata } from '../metadata/Metadata.js';
import { PresenceManager } from './PresenceManager.js';
Expand Down Expand Up @@ -144,10 +147,17 @@ export class PushPullSync
this.emit('message', message);
};

// reduce rate of presence messages sent; each one would trigger an HTTP
// request, which is not ideal if presence is updating rapidly.
throttledPresenceUpdate = throttle((message: PresenceUpdateMessage) => {
this.sendRequest([message]);
}, 3000);

send = (message: ClientMessage) => {
// only certain messages are sent for pull-based sync.
switch (message.type) {
case 'presence-update':
return this.throttledPresenceUpdate(message);
case 'sync':
case 'heartbeat':
return this.sendRequest([message]);
Expand Down

0 comments on commit d876471

Please sign in to comment.