Skip to content

Commit f881992

Browse files
Listen for database close events to catch closed items earlier.
1 parent cbfb683 commit f881992

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

packages/web/src/db/adapters/LockedAsyncDatabaseAdapter.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,27 @@ export class LockedAsyncDatabaseAdapter
132132
this.requiresHolds = (this._config as ResolvedWASQLiteOpenFactoryOptions).vfs == WASQLiteVFS.IDBBatchAtomicVFS;
133133
}
134134

135+
protected _reOpen() {
136+
this.databaseOpenPromise = this.openInternalDB().finally(() => {
137+
this.databaseOpenPromise = null;
138+
});
139+
return this.databaseOpenPromise;
140+
}
141+
142+
/**
143+
* Re-opens the underlying database.
144+
* Returns a pending operation if one is already in progress.
145+
*/
146+
async reOpenInternalDB(): Promise<void> {
147+
if (!this.options.reOpenOnConnectionClosed) {
148+
throw new Error(`Cannot re-open underlying database, reOpenOnConnectionClosed is not enabled`);
149+
}
150+
if (this.databaseOpenPromise) {
151+
return this.databaseOpenPromise;
152+
}
153+
return this._reOpen();
154+
}
155+
135156
protected async _init() {
136157
await this.openInternalDB();
137158
this.iterateListeners((cb) => cb.initialized?.());
@@ -277,9 +298,7 @@ export class LockedAsyncDatabaseAdapter
277298
if (ex instanceof ConnectionClosedError) {
278299
if (this.options.reOpenOnConnectionClosed && !this.databaseOpenPromise && !this.closing) {
279300
// Immediately re-open the database. We need to miss as little table updates as possible.
280-
this.databaseOpenPromise = this.openInternalDB().finally(() => {
281-
this.databaseOpenPromise = null;
282-
});
301+
this.reOpenInternalDB();
283302
}
284303
}
285304
throw ex;

packages/web/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { BaseObserver } from '@powersync/common';
12
import * as Comlink from 'comlink';
23
import {
34
AsyncDatabaseConnection,
@@ -24,17 +25,23 @@ export type WrappedWorkerConnectionOptions<Config extends ResolvedWebSQLOpenOpti
2425
onClose?: () => void;
2526
};
2627

28+
export type WorkerWrappedAsyncDatabaseConnectionListener = {
29+
closing: () => void;
30+
};
2731
/**
2832
* Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy
2933
* functions for worker listeners.
3034
*/
3135
export class WorkerWrappedAsyncDatabaseConnection<Config extends ResolvedWebSQLOpenOptions = ResolvedWebSQLOpenOptions>
36+
extends BaseObserver<WorkerWrappedAsyncDatabaseConnectionListener>
3237
implements AsyncDatabaseConnection
3338
{
3439
protected lockAbortController = new AbortController();
3540
protected notifyRemoteClosed: AbortController | undefined;
3641

3742
constructor(protected options: WrappedWorkerConnectionOptions<Config>) {
43+
super();
44+
3845
if (options.remoteCanCloseUnexpectedly) {
3946
this.notifyRemoteClosed = new AbortController();
4047
}
@@ -169,6 +176,7 @@ export class WorkerWrappedAsyncDatabaseConnection<Config extends ResolvedWebSQLO
169176
} finally {
170177
this.options.remote[Comlink.releaseProxy]();
171178
this.options.onClose?.();
179+
this.iterateListeners((l) => l.closing?.());
172180
}
173181
}
174182

packages/web/src/worker/sync/SharedSyncImplementation.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,13 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
247247
name: params.dbParams.dbFilename,
248248
openConnection: async () => {
249249
// Gets a connection from the clients when a new connection is requested.
250-
return await this.openInternalDB();
250+
const db = await this.openInternalDB();
251+
db.registerListener({
252+
closing: () => {
253+
lockedAdapter.reOpenInternalDB();
254+
}
255+
});
256+
return db;
251257
},
252258
logger: this.logger,
253259
reOpenOnConnectionClosed: true

0 commit comments

Comments
 (0)