Skip to content

Commit

Permalink
fix(zero-cache): avoid perpetuating work when clients have disconnect…
Browse files Browse the repository at this point in the history
…ed (#3408)
  • Loading branch information
darkgnotic authored Dec 18, 2024
1 parent c45b233 commit 3f33517
Showing 1 changed file with 11 additions and 12 deletions.
23 changes: 11 additions & 12 deletions packages/zero-cache/src/services/view-syncer/view-syncer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class ViewSyncerService implements ViewSyncer, ActivityBasedService {
return; // view-syncer has been shutdown
}
// If all clients have disconnected, cancel all pending work.
if (this.#checkForShutdownConditionsInLock()) {
if (await this.#checkForShutdownConditionsInLock()) {
this.#lc.info?.('shutting down');
this.#stateChanges.cancel(); // Note: #stateChanges.active becomes false.
return;
Expand Down Expand Up @@ -278,31 +278,30 @@ export class ViewSyncerService implements ViewSyncer, ActivityBasedService {
this.#shutdownTimer ??= setTimeout(async () => {
this.#shutdownTimer = null;

// Keep the view-syncer alive if there are pending rows being flushed.
// It's better to do this before shutting down since it may take a
// while, during which new connections may come in.
await this.#cvrStore.flushed(this.#lc).catch(e => this.#lc.error?.(e));

// All lock tasks check for shutdown so that queued work is immediately
// canceled when clients disconnect. Queue an empty task to ensure that
// this check happens.
await this.#runInLockWithCVR(() => {});
}, delayMs);
}

#checkForShutdownConditionsInLock(): boolean {
async #checkForShutdownConditionsInLock(): Promise<boolean> {
if (this.#clients.size > 0) {
return false; // common case.
}

// Keep the view-syncer alive if there are pending rows being flushed.
// It's better to do this before shutting down since it may take a
// while, during which new connections may come in.
await this.#cvrStore.flushed(this.#lc);

if (Date.now() <= this.#keepAliveUntil) {
this.#scheduleShutdown(this.#keepaliveMs); // check again later
return false;
}
if (this.#cvrStore.hasPendingUpdates()) {
this.#scheduleShutdown(0); // check again after #cvrStore.flushed()
return false;
}
return true;

// If no clients have connected while waiting for the row flush, shutdown.
return this.#clients.size === 0;
}

#deleteClient(clientID: string, client: ClientHandler) {
Expand Down

0 comments on commit 3f33517

Please sign in to comment.