feat(nbstore): add nbstore worker (#9185)

This commit is contained in:
EYHN
2024-12-20 08:01:23 +00:00
parent 30200ff86d
commit cbaf35df0b
51 changed files with 1144 additions and 501 deletions

View File

@@ -3,7 +3,16 @@ import type {
AwarenessStorage,
} from '../../storage/awareness';
export class AwarenessSync {
export interface AwarenessSync {
update(record: AwarenessRecord, origin?: string): Promise<void>;
subscribeUpdate(
id: string,
onUpdate: (update: AwarenessRecord, origin?: string) => void,
onCollect: () => Promise<AwarenessRecord | null>
): () => void;
}
export class AwarenessSyncImpl implements AwarenessSync {
constructor(
readonly local: AwarenessStorage,
readonly remotes: AwarenessStorage[]
@@ -18,7 +27,7 @@ export class AwarenessSync {
subscribeUpdate(
id: string,
onUpdate: (update: AwarenessRecord, origin?: string) => void,
onCollect: () => AwarenessRecord
onCollect: () => Promise<AwarenessRecord | null>
): () => void {
const unsubscribes = [this.local, ...this.remotes].map(peer =>
peer.subscribeUpdate(id, onUpdate, onCollect)

View File

@@ -3,7 +3,15 @@ import { difference } from 'lodash-es';
import type { BlobRecord, BlobStorage } from '../../storage';
import { MANUALLY_STOP, throwIfAborted } from '../../utils/throw-if-aborted';
export class BlobSync {
export interface BlobSync {
downloadBlob(
blobId: string,
signal?: AbortSignal
): Promise<BlobRecord | null>;
uploadBlob(blob: BlobRecord, signal?: AbortSignal): Promise<void>;
}
export class BlobSyncImpl implements BlobSync {
private abort: AbortController | null = null;
constructor(

View File

@@ -17,7 +17,13 @@ export interface DocSyncDocState {
errorMessage: string | null;
}
export class DocSync {
export interface DocSync {
readonly state$: Observable<DocSyncState>;
docState$(docId: string): Observable<DocSyncDocState>;
addPriority(id: string, priority: number): () => void;
}
export class DocSyncImpl implements DocSync {
private readonly peers: DocSyncPeer[] = this.remotes.map(
remote => new DocSyncPeer(this.local, this.sync, remote)
);

View File

@@ -92,7 +92,7 @@ export class DocSyncPeer {
/**
* random unique id for recognize self in "update" event
*/
private readonly uniqueId = `sync:${this.local.peer}:${this.remote.peer}:${nanoid()}`;
private readonly uniqueId = `sync:${this.local.universalId}:${this.remote.universalId}:${nanoid()}`;
private readonly prioritySettings = new Map<string, number>();
constructor(
@@ -435,7 +435,6 @@ export class DocSyncPeer {
};
async mainLoop(signal?: AbortSignal) {
// eslint-disable-next-line no-constant-condition
while (true) {
try {
await this.retryLoop(signal);
@@ -594,12 +593,12 @@ export class DocSyncPeer {
}
// begin to process jobs
// eslint-disable-next-line no-constant-condition
while (true) {
throwIfAborted(signal);
const docId = await this.status.jobDocQueue.asyncPop(signal);
// eslint-disable-next-line no-constant-condition
while (true) {
// batch process jobs for the same doc
const jobs = this.status.jobMap.get(docId);

View File

@@ -1,19 +1,23 @@
import { combineLatest, map, type Observable, of } from 'rxjs';
import type { BlobStorage, DocStorage, SpaceStorage } from '../storage';
import type { AwarenessStorage } from '../storage/awareness';
import { AwarenessSync } from './awareness';
import { BlobSync } from './blob';
import { DocSync, type DocSyncState } from './doc';
import type {
AwarenessStorage,
BlobStorage,
DocStorage,
SpaceStorage,
} from '../storage';
import { AwarenessSyncImpl } from './awareness';
import { BlobSyncImpl } from './blob';
import { DocSyncImpl, type DocSyncState } from './doc';
export interface SyncState {
doc?: DocSyncState;
}
export class Sync {
readonly doc: DocSync | null;
readonly blob: BlobSync | null;
readonly awareness: AwarenessSync | null;
readonly doc: DocSyncImpl | null;
readonly blob: BlobSyncImpl | null;
readonly awareness: AwarenessSyncImpl | null;
readonly state$: Observable<SyncState>;
@@ -28,7 +32,7 @@ export class Sync {
this.doc =
doc && sync
? new DocSync(
? new DocSyncImpl(
doc,
sync,
peers
@@ -37,7 +41,7 @@ export class Sync {
)
: null;
this.blob = blob
? new BlobSync(
? new BlobSyncImpl(
blob,
peers
.map(peer => peer.tryGet('blob'))
@@ -45,7 +49,7 @@ export class Sync {
)
: null;
this.awareness = awareness
? new AwarenessSync(
? new AwarenessSyncImpl(
awareness,
peers
.map(peer => peer.tryGet('awareness'))