mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 10:06:17 +08:00
feat(nbstore): add doc sync frontend (#9070)
This commit is contained in:
@@ -4,6 +4,8 @@ import type { BlobStorage } from '../../storage';
|
||||
import { MANUALLY_STOP, throwIfAborted } from '../../utils/throw-if-aborted';
|
||||
|
||||
export class BlobSyncEngine {
|
||||
private abort: AbortController | null = null;
|
||||
|
||||
constructor(
|
||||
readonly local: BlobStorage,
|
||||
readonly remotes: BlobStorage[]
|
||||
@@ -72,18 +74,24 @@ export class BlobSyncEngine {
|
||||
}
|
||||
}
|
||||
|
||||
async run(signal?: AbortSignal) {
|
||||
if (signal?.aborted) {
|
||||
return;
|
||||
start() {
|
||||
if (this.abort) {
|
||||
this.abort.abort();
|
||||
}
|
||||
|
||||
try {
|
||||
await this.sync(signal);
|
||||
} catch (error) {
|
||||
const abort = new AbortController();
|
||||
this.abort = abort;
|
||||
|
||||
this.sync(abort.signal).catch(error => {
|
||||
if (error === MANUALLY_STOP) {
|
||||
return;
|
||||
}
|
||||
console.error('sync blob error', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.abort?.abort();
|
||||
this.abort = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,37 @@ import type { DocStorage, SyncStorage } from '../../storage';
|
||||
import { DocSyncPeer } from './peer';
|
||||
|
||||
export class DocSyncEngine {
|
||||
private readonly peers: DocSyncPeer[];
|
||||
private abort: AbortController | null = null;
|
||||
|
||||
constructor(
|
||||
readonly local: DocStorage,
|
||||
readonly sync: SyncStorage,
|
||||
readonly peers: DocStorage[]
|
||||
) {}
|
||||
readonly remotes: DocStorage[]
|
||||
) {
|
||||
this.peers = remotes.map(remote => new DocSyncPeer(local, sync, remote));
|
||||
}
|
||||
|
||||
async run(signal?: AbortSignal) {
|
||||
await Promise.all(
|
||||
this.peers.map(peer =>
|
||||
new DocSyncPeer(this.local, this.sync, peer).mainLoop(signal)
|
||||
)
|
||||
);
|
||||
start() {
|
||||
if (this.abort) {
|
||||
this.abort.abort();
|
||||
}
|
||||
const abort = new AbortController();
|
||||
this.abort = abort;
|
||||
Promise.allSettled(
|
||||
this.peers.map(peer => peer.mainLoop(abort.signal))
|
||||
).catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.abort?.abort();
|
||||
this.abort = null;
|
||||
}
|
||||
|
||||
addPriority(id: string, priority: number) {
|
||||
const undo = this.peers.map(peer => peer.addPriority(id, priority));
|
||||
return () => undo.forEach(fn => fn());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,11 +610,6 @@ export class DocSyncPeer {
|
||||
this.statusUpdatedSubject$.next(job.docId);
|
||||
}
|
||||
|
||||
setPriority(docId: string, priority: number) {
|
||||
this.prioritySettings.set(docId, priority);
|
||||
return this.status.jobDocQueue.setPriority(docId, priority);
|
||||
}
|
||||
|
||||
addPriority(id: string, priority: number) {
|
||||
const oldPriority = this.prioritySettings.get(id) ?? 0;
|
||||
this.prioritySettings.set(id, priority);
|
||||
|
||||
@@ -3,37 +3,44 @@ import { BlobSyncEngine } from './blob';
|
||||
import { DocSyncEngine } from './doc';
|
||||
|
||||
export class SyncEngine {
|
||||
private readonly doc: DocSyncEngine | null;
|
||||
private readonly blob: BlobSyncEngine | null;
|
||||
|
||||
constructor(
|
||||
readonly local: SpaceStorage,
|
||||
readonly peers: SpaceStorage[]
|
||||
) {}
|
||||
) {
|
||||
const doc = local.tryGet('doc');
|
||||
const blob = local.tryGet('blob');
|
||||
const sync = local.tryGet('sync');
|
||||
|
||||
async run(signal?: AbortSignal) {
|
||||
const doc = this.local.tryGet('doc');
|
||||
const blob = this.local.tryGet('blob');
|
||||
const sync = this.local.tryGet('sync');
|
||||
|
||||
await Promise.allSettled([
|
||||
(async () => {
|
||||
if (doc && sync) {
|
||||
const peerDocs = this.peers
|
||||
.map(peer => peer.tryGet('doc'))
|
||||
.filter((v): v is DocStorage => !!v);
|
||||
|
||||
const engine = new DocSyncEngine(doc, sync, peerDocs);
|
||||
await engine.run(signal);
|
||||
}
|
||||
})(),
|
||||
(async () => {
|
||||
if (blob) {
|
||||
const peerBlobs = this.peers
|
||||
this.doc =
|
||||
doc && sync
|
||||
? new DocSyncEngine(
|
||||
doc,
|
||||
sync,
|
||||
peers
|
||||
.map(peer => peer.tryGet('doc'))
|
||||
.filter((v): v is DocStorage => !!v)
|
||||
)
|
||||
: null;
|
||||
this.blob = blob
|
||||
? new BlobSyncEngine(
|
||||
blob,
|
||||
peers
|
||||
.map(peer => peer.tryGet('blob'))
|
||||
.filter((v): v is BlobStorage => !!v);
|
||||
.filter((v): v is BlobStorage => !!v)
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
const engine = new BlobSyncEngine(blob, peerBlobs);
|
||||
await engine.run(signal);
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
start() {
|
||||
this.doc?.start();
|
||||
this.blob?.start();
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.doc?.stop();
|
||||
this.blob?.stop();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user