feat(nbstore): remove async on connection api (#9187)

We should not use async on `connect` and `disconnect`, for `WebSocketConnection` will never connect when offline.

We should handle the connection status of each storage in sync, using the `connection.waitForConnect`

This PR also puts the connection reference count on the `connect` and disconnect`
This commit is contained in:
EYHN
2024-12-18 03:59:49 +00:00
parent 3fddf050a4
commit 64b017dc1b
20 changed files with 160 additions and 226 deletions

View File

@@ -1,10 +1,5 @@
import { dialogHandlers } from './dialog';
import {
dbEventsV1,
dbHandlersV1,
nbstoreEvents,
nbstoreHandlers,
} from './nbstore';
import { dbEventsV1, dbHandlersV1, nbstoreHandlers } from './nbstore';
import { provideExposed } from './provide';
import { workspaceEvents, workspaceHandlers } from './workspace';
@@ -18,7 +13,6 @@ export const handlers = {
export const events = {
db: dbEventsV1,
workspace: workspaceEvents,
nbstore: nbstoreEvents,
};
const getExposedMeta = () => {

View File

@@ -33,8 +33,14 @@ export class NativeDBConnection extends Connection<NativeDocStorage> {
return conn;
}
override async doDisconnect(conn: NativeDocStorage) {
await conn.close();
logger.info('[nbstore] connection closed', this.shareId);
override doDisconnect(conn: NativeDocStorage) {
conn
.close()
.then(() => {
logger.info('[nbstore] connection closed', this.shareId);
})
.catch(err => {
logger.error('[nbstore] connection close failed', this.shareId, err);
});
}
}

View File

@@ -4,13 +4,7 @@ import {
type DocUpdate,
} from '@affine/nbstore';
import type { MainEventRegister } from '../type';
import {
type ConnectionStatus,
ensureStorage,
getStorage,
onConnectionChanged,
} from './storage';
import { ensureStorage, getStorage } from './storage';
export const nbstoreHandlers = {
connect: async (id: string) => {
@@ -21,7 +15,7 @@ export const nbstoreHandlers = {
const store = getStorage(id);
if (store) {
await store.disconnect();
store.disconnect();
// The store may be shared with other tabs, so we don't delete it from cache
// the underlying connection will handle the close correctly
// STORE_CACHE.delete(`${spaceType}:${spaceId}`);
@@ -132,12 +126,3 @@ export const nbstoreHandlers = {
return store.get('sync').clearClocks();
},
};
export const nbstoreEvents = {
onConnectionStatusChanged: (fn: (payload: ConnectionStatus) => void) => {
const sub = onConnectionChanged(fn);
return () => {
sub.unsubscribe();
};
},
} satisfies Record<string, MainEventRegister>;

View File

@@ -1,4 +1,4 @@
export { nbstoreEvents, nbstoreHandlers } from './handlers';
export { nbstoreHandlers } from './handlers';
export * from './storage';
export { dbEvents as dbEventsV1, dbHandlers as dbHandlersV1 } from './v1';
export { universalId } from '@affine/nbstore';

View File

@@ -1,10 +1,4 @@
import {
parseUniversalId,
SpaceStorage,
type SpaceType,
type StorageType,
} from '@affine/nbstore';
import { Subject } from 'rxjs';
import { parseUniversalId, SpaceStorage } from '@affine/nbstore';
import { applyUpdate, Doc as YDoc } from 'yjs';
import { logger } from '../logger';
@@ -57,18 +51,8 @@ export class SqliteSpaceStorage extends SpaceStorage {
}
const STORE_CACHE = new Map<string, SqliteSpaceStorage>();
export interface ConnectionStatus {
peer: string;
spaceType: SpaceType;
spaceId: string;
storage: StorageType;
status: string;
error?: Error;
}
const CONNECTION$ = new Subject<ConnectionStatus>();
process.on('beforeExit', () => {
CONNECTION$.complete();
STORE_CACHE.forEach(store => {
store.destroy().catch(err => {
logger.error('[nbstore] destroy store failed', err);
@@ -76,10 +60,6 @@ process.on('beforeExit', () => {
});
});
export function onConnectionChanged(fn: (payload: ConnectionStatus) => void) {
return CONNECTION$.subscribe({ next: fn });
}
export function getStorage(universalId: string) {
return STORE_CACHE.get(universalId);
}
@@ -101,24 +81,9 @@ export async function ensureStorage(universalId: string) {
new SqliteSyncStorage(opts),
]);
store.on('connection', ({ storage, status, error }) => {
CONNECTION$.next({
peer,
spaceType: type,
spaceId: id,
storage,
status,
error,
});
logger.info(
`[nbstore] status changed: ${status}, spaceType: ${type}, spaceId: ${id}, storage: ${storage}`
);
if (error) {
logger.error(`[nbstore] connection error: ${error}`);
}
});
store.connect();
await store.connect();
await store.waitForConnected();
STORE_CACHE.set(universalId, store);
}