perf(core): only full sync before exporting (#10408)

This commit is contained in:
liuyi
2025-02-25 12:41:56 +08:00
committed by GitHub
parent c644a46b8d
commit e5e5c0a8ba
8 changed files with 222 additions and 120 deletions

View File

@@ -8,8 +8,8 @@ import type { Workspace } from '@affine/core/modules/workspace';
import { useI18n } from '@affine/i18n';
import { universalId } from '@affine/nbstore';
import track from '@affine/track';
import { useService } from '@toeverything/infra';
import { useState } from 'react';
import { LiveData, useLiveData, useService } from '@toeverything/infra';
import { useMemo, useState } from 'react';
interface ExportPanelProps {
workspace: Workspace;
@@ -20,9 +20,44 @@ export const DesktopExportPanel = ({ workspace }: ExportPanelProps) => {
const [saving, setSaving] = useState(false);
const isOnline = useSystemOnline();
const desktopApi = useService(DesktopApiService);
const isLocalWorkspace = workspace.flavour === 'local';
const docSyncState = useLiveData(
useMemo(() => {
return workspace
? LiveData.from(workspace.engine.doc.state$, null).throttleTime(500)
: null;
}, [workspace])
);
const blobSyncState = useLiveData(
useMemo(() => {
return workspace
? LiveData.from(workspace.engine.blob.state$, null).throttleTime(500)
: null;
}, [workspace])
);
const docSynced = !docSyncState?.syncing;
const blobSynced =
!blobSyncState || blobSyncState.synced === blobSyncState.total;
const [fullSynced, setFullSynced] = useState(false);
const shouldWaitForFullSync =
isLocalWorkspace || !isOnline || (fullSynced && docSynced && blobSynced);
const fullSyncing = fullSynced && (!docSynced || !blobSynced);
const fullSync = useAsyncCallback(async () => {
// NOTE: doc full sync is always started by default
// await workspace.engine.doc.waitForSynced();
workspace.engine.blob.fullDownload().catch(() => {
/* noop */
});
setFullSynced(true);
}, [workspace.engine.blob]);
const onExport = useAsyncCallback(async () => {
if (saving || !workspace) {
if (saving) {
return;
}
setSaving(true);
@@ -30,10 +65,6 @@ export const DesktopExportPanel = ({ workspace }: ExportPanelProps) => {
track.$.settingsPanel.workspace.export({
type: 'workspace',
});
if (isOnline) {
await workspace.engine.doc.waitForSynced();
await workspace.engine.blob.fullSync();
}
const result = await desktopApi.handler?.dialog.saveDBFileAs(
universalId({
@@ -53,16 +84,37 @@ export const DesktopExportPanel = ({ workspace }: ExportPanelProps) => {
} finally {
setSaving(false);
}
}, [desktopApi, isOnline, saving, t, workspace]);
}, [desktopApi, saving, t, workspace]);
if (!shouldWaitForFullSync) {
return (
<SettingRow name={t['Export']()} desc={t['Full Sync Description']()}>
<Button
data-testid="export-affine-full-sync"
onClick={fullSync}
loading={fullSyncing}
>
{t['Full Sync']()}
</Button>
</SettingRow>
);
}
const button =
isLocalWorkspace || isOnline ? t['Export']() : t['Export(Offline)']();
const desc =
isLocalWorkspace || isOnline
? t['Export Description']()
: t['Export Description(Offline)']();
return (
<SettingRow name={t['Export']()} desc={t['Export Description']()}>
<SettingRow name={t['Export']()} desc={desc}>
<Button
data-testid="export-affine-backup"
onClick={onExport}
disabled={saving}
>
{t['Export']()}
{button}
</Button>
</SettingRow>
);