mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
feat(nbstore): add nbstore worker (#9185)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'))
|
||||
|
||||
Reference in New Issue
Block a user