Skip to content

Commit a806668

Browse files
authored
Batch tracked users setup (#40)
The intention here is to handle things when thousands of requests are made to add tracked users and the async lock gets dogpiled. Async lock has a (sensible) limit of 1000 acquires before it gives up, so I think we should just queue up requests in a big batch and handle them like so. ## Checklist * [ ] Tests written for all new code * [ ] Linter has been satisfied * [ ] Sign-off given on the changes (see CONTRIBUTING.md)
2 parents da2792e + e95019d commit a806668

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/e2ee/RustEngine.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export const SYNC_LOCK_NAME = "sync";
3333
export class RustEngine {
3434
public readonly lock = new AsyncLock();
3535

36+
public readonly trackedUsersToAdd = new Set<string>();
37+
public addTrackedUsersPromise: Promise<void>|undefined;
38+
3639
private keyBackupVersion: KeyBackupVersion|undefined;
3740
private keyBackupWaiter = Promise.resolve();
3841

@@ -80,8 +83,22 @@ export class RustEngine {
8083
}
8184

8285
public async addTrackedUsers(userIds: string[]) {
83-
await this.lock.acquire(SYNC_LOCK_NAME, async () => {
84-
const uids = userIds.map(u => new UserId(u));
86+
// Add the new set of users to the pool
87+
userIds.forEach(uId => this.trackedUsersToAdd.add(uId));
88+
if (this.addTrackedUsersPromise) {
89+
// If we have a pending promise, don't create another lock requirement.
90+
return;
91+
}
92+
return this.addTrackedUsersPromise = this.lock.acquire(SYNC_LOCK_NAME, async () => {
93+
// Immediately clear this promise so that a new promise is queued up.
94+
this.addTrackedUsersPromise = undefined;
95+
const uids = new Array<UserId>(this.trackedUsersToAdd.size);
96+
let idx = 0;
97+
for (const u of this.trackedUsersToAdd.values()) {
98+
uids[idx++] = new UserId(u);
99+
}
100+
// Clear the existing pool
101+
this.trackedUsersToAdd.clear();
85102
await this.machine.updateTrackedUsers(uids);
86103

87104
const keysClaim = await this.machine.getMissingSessions(uids);

0 commit comments

Comments
 (0)