refactor(workspace): blob sync (#5037)

This pr implements a blob engine.
It exposes a single `BlobStorage` to the `blocksuite`, and in it we sync blobs between multiple storages.

The implement still have few issues, but we can merge this pr first and fix them in future.

* BlobEngine currently **do nothing when delete**, because synchronization logic conflicts with deletion logic.
* BlobEngine sync between storages by querying the blob list at regular intervals. This will **cause many queries**, we can avoid this in the future by subscribing to remote changes.
This commit is contained in:
EYHN
2023-11-23 07:56:19 +00:00
parent 1740e7efa1
commit 23e0137ed8
13 changed files with 423 additions and 174 deletions

View File

@@ -14,6 +14,7 @@ import {
} from '@affine/component/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
import { getBlobEngine } from '@affine/workspace/manager';
import { assertExists } from '@blocksuite/global/utils';
import type { DragEndEvent } from '@dnd-kit/core';
import {
@@ -116,10 +117,44 @@ type WorkspaceLayoutProps = {
migration?: MigrationPoint;
};
const useSyncWorkspaceBlob = () => {
// temporary solution for sync blob
const [currentWorkspace] = useCurrentWorkspace();
useEffect(() => {
const blobEngine = getBlobEngine(currentWorkspace.blockSuiteWorkspace);
let stopped = false;
function sync() {
if (stopped) {
return;
}
blobEngine
?.sync()
.catch(error => {
console.error('sync blob error', error);
})
.finally(() => {
// sync every 1 minute
setTimeout(sync, 60000);
});
}
// after currentWorkspace changed, wait 1 second to start sync
setTimeout(sync, 1000);
return () => {
stopped = true;
};
}, [currentWorkspace]);
};
export const WorkspaceLayout = function WorkspacesSuspense({
children,
migration,
}: PropsWithChildren<WorkspaceLayoutProps>) {
useSyncWorkspaceBlob();
return (
<AdapterProviderWrapper>
<CurrentWorkspaceContext>