Skip to content

Commit

Permalink
fix(server): wrong doc response branch tests (#6250)
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo authored and EYHN committed Mar 21, 2024
1 parent 186ec7a commit f1db0b4
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 3 deletions.
4 changes: 2 additions & 2 deletions packages/backend/server/src/core/doc/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ export class DocManager implements OnModuleInit, OnModuleDestroy {
if (result) {
if ('doc' in result) {
return result;
} else if ('snapshot' in result) {
} else {
const doc = await this.recoverDoc(result.binary);

return {
Expand All @@ -420,7 +420,7 @@ export class DocManager implements OnModuleInit, OnModuleDestroy {
binary: Buffer.from(encodeStateAsUpdate(result.doc)),
timestamp: result.timestamp,
};
} else if ('snapshot' in result) {
} else {
return result;
}
}
Expand Down
14 changes: 14 additions & 0 deletions packages/common/infra/src/storage/kv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export interface ByteKV extends ByteKVBehavior {
export interface ByteKVBehavior {
get(key: string): Promise<Uint8Array | null> | Uint8Array | null;
set(key: string, value: Uint8Array): Promise<void> | void;
del(key: string): Promise<void> | void;
keys(): Promise<string[]> | string[];
clear(): Promise<void> | void;
}

export class MemoryByteKV implements ByteKV {
Expand All @@ -27,6 +29,12 @@ export class MemoryByteKV implements ByteKV {
keys: async () => {
return Array.from(this.db.keys());
},
del: async key => {
this.db.delete(key);
},
clear: async () => {
this.db.clear();
},
});
}
get(key: string) {
Expand All @@ -38,6 +46,12 @@ export class MemoryByteKV implements ByteKV {
keys() {
return this.transaction(async tx => tx.keys());
}
clear() {
return this.transaction(async tx => tx.clear());
}
del(key: string) {
return this.transaction(async tx => tx.del(key));
}
}

export class ReadonlyByteKV extends MemoryByteKV implements ByteKV {
Expand Down
18 changes: 18 additions & 0 deletions packages/common/infra/src/storage/memento.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface Memento {
get<T>(key: string): T | null;
watch<T>(key: string): Observable<T | null>;
set<T>(key: string, value: T | null): void;
del(key: string): void;
clear(): void;
keys(): string[];
}

Expand Down Expand Up @@ -58,6 +60,12 @@ export class MemoryMemento implements Memento {
keys(): string[] {
return Array.from(this.data.keys());
}
clear(): void {
this.data.clear();
}
del(key: string): void {
this.data.delete(key);
}
}

export function wrapMemento(memento: Memento, prefix: string): Memento {
Expand All @@ -77,5 +85,15 @@ export function wrapMemento(memento: Memento, prefix: string): Memento {
.filter(k => k.startsWith(prefix))
.map(k => k.slice(prefix.length));
},
clear() {
memento.keys().forEach(k => {
if (k.startsWith(prefix)) {
memento.del(k);
}
});
},
del(key: string): void {
memento.del(prefix + key);
},
};
}
6 changes: 6 additions & 0 deletions packages/common/infra/src/workspace/engine/doc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ export class DocEngine {
this.abort.abort(MANUALLY_STOP);
}

async resetSyncStatus() {
this.stop();
await this.storage.clearSyncMetadata();
await this.storage.clearServerClock();
}

addDoc(doc: YDoc, withSubDocs = true) {
this.localPart.actions.addDoc(doc);
this.remotePart?.actions.addDoc(doc.guid);
Expand Down
44 changes: 44 additions & 0 deletions packages/common/infra/src/workspace/engine/doc/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ export class StorageInner {

return await this.saveDocSeqNum(docId, true);
}

clearSyncMetadata() {
return this.behavior.syncMetadata.clear();
}

async clearServerClock() {
return this.behavior.serverClock.clear();
}
}

export class ReadonlyStorage implements Storage {
Expand Down Expand Up @@ -247,6 +255,12 @@ export class MemoryStorage implements Storage {
keys: async () => {
return Array.from(this.docDb.keys());
},
clear: () => {
this.docDb.clear();
},
del: key => {
this.docDb.del(key);
},
});
},
get(key) {
Expand All @@ -258,6 +272,12 @@ export class MemoryStorage implements Storage {
keys() {
return this.transaction(async tx => tx.keys());
},
clear() {
return this.transaction(async tx => tx.clear());
},
del(key) {
return this.transaction(async tx => tx.del(key));
},
} satisfies ByteKV;

readonly syncMetadata = {
Expand All @@ -273,6 +293,12 @@ export class MemoryStorage implements Storage {
keys: async () => {
return Array.from(this.syncMetadataDb.keys());
},
clear: () => {
this.syncMetadataDb.clear();
},
del: key => {
this.syncMetadataDb.del(key);
},
});
},
get(key) {
Expand All @@ -284,6 +310,12 @@ export class MemoryStorage implements Storage {
keys() {
return this.transaction(async tx => tx.keys());
},
clear() {
return this.transaction(async tx => tx.clear());
},
del(key) {
return this.transaction(async tx => tx.del(key));
},
} satisfies ByteKV;

readonly serverClock = {
Expand All @@ -299,6 +331,12 @@ export class MemoryStorage implements Storage {
keys: async () => {
return Array.from(this.serverClockDb.keys());
},
clear: () => {
this.serverClockDb.clear();
},
del: key => {
this.serverClockDb.del(key);
},
});
},
get(key) {
Expand All @@ -310,5 +348,11 @@ export class MemoryStorage implements Storage {
keys() {
return this.transaction(async tx => tx.keys());
},
clear() {
return this.transaction(async tx => tx.clear());
},
del(key) {
return this.transaction(async tx => tx.del(key));
},
} satisfies ByteKV;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { useWorkspace } from '@affine/core/hooks/use-workspace';
import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowRightSmallIcon } from '@blocksuite/icons';
import { useCallback } from 'react';

import { DeleteLeaveWorkspace } from './delete-leave-workspace';
import { EnableCloudPanel } from './enable-cloud';
Expand All @@ -29,6 +31,17 @@ export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => {

const workspaceInfo = useWorkspaceInfo(workspaceMetadata);

const handleResetSyncStatus = useCallback(() => {
workspace?.engine.doc
.resetSyncStatus()
.then(() => {
window.location.reload();
})
.catch(err => {
console.error(err);
});
}, [workspace]);

return (
<>
<SettingHeader
Expand Down Expand Up @@ -64,6 +77,19 @@ export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => {
)}
<SettingWrapper>
<DeleteLeaveWorkspace {...props} />
<SettingRow
name={
<span style={{ color: 'var(--affine-text-secondary-color)' }}>
{t['com.affine.resetSyncStatus.button']()}
</span>
}
desc={t['com.affine.resetSyncStatus.description']()}
style={{ cursor: 'pointer' }}
onClick={handleResetSyncStatus}
data-testid="reset-sync-status"
>
<ArrowRightSmallIcon />
</SettingRow>
</SettingWrapper>
</>
);
Expand Down
10 changes: 10 additions & 0 deletions packages/frontend/core/src/modules/infra-web/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ export class LocalStorageMemento implements Memento {
channel.postMessage(value);
channel.close();
}

del(key: string): void {
localStorage.removeItem(this.prefix + key);
}

clear(): void {
for (const key of this.keys()) {
this.del(key);
}
}
}

export class LocalStorageGlobalCache
Expand Down
4 changes: 3 additions & 1 deletion packages/frontend/i18n/src/resources/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1165,5 +1165,7 @@
"com.affine.delete-tags.count_other": "{{count}} tags deleted",
"com.affine.workbench.split-view-menu.keep-this-one": "Solo View",
"com.affine.workbench.split-view.page-menu-open": "Open in split view",
"com.affine.search-tags.placeholder": "Type here ..."
"com.affine.search-tags.placeholder": "Type here ...",
"com.affine.resetSyncStatus.button": "Reset Sync",
"com.affine.resetSyncStatus.description": "This operation may fix some synchronization issues."
}
8 changes: 8 additions & 0 deletions packages/frontend/workspace-impl/src/local-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ export class WorkspaceLocalStateImpl implements WorkspaceLocalState {
set<T>(key: string, value: T | null): void {
return this.wrapped.set<T>(key, value);
}

del(key: string): void {
return this.wrapped.del(key);
}

clear(): void {
return this.wrapped.clear();
}
}
37 changes: 37 additions & 0 deletions packages/frontend/workspace-impl/src/local/doc-indexeddb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ class Doc implements DocType {
return store.getAllKeys();
}

clear(): void | Promise<void> {
return;
}

del(_key: string): void | Promise<void> {
return;
}

async transaction<T>(
cb: (transaction: ByteKVBehavior) => Promise<T>
): Promise<T> {
Expand Down Expand Up @@ -130,6 +138,12 @@ class Doc implements DocType {
updates: rows,
});
},
async clear() {
return await store.clear();
},
async del(key) {
return store.delete(key);
},
});
}
}
Expand Down Expand Up @@ -185,6 +199,16 @@ class KV implements ByteKV {
const store = db.transaction('kv', 'readwrite').objectStore('kv');
return new KVBehavior(store).keys();
}
async clear() {
const db = await this.getDb();
const store = db.transaction('kv', 'readwrite').objectStore('kv');
return new KVBehavior(store).clear();
}
async del(key: string) {
const db = await this.getDb();
const store = db.transaction('kv', 'readwrite').objectStore('kv');
return new KVBehavior(store).del(key);
}
}

class KVBehavior implements ByteKVBehavior {
Expand All @@ -207,4 +231,17 @@ class KVBehavior implements ByteKVBehavior {
async keys(): Promise<string[]> {
return await this.store.getAllKeys();
}
async del(key: string) {
if (this.store.delete === undefined) {
throw new Error('Cannot set in a readonly transaction');
}
return await this.store.delete(key);
}

async clear() {
if (this.store.clear === undefined) {
throw new Error('Cannot set in a readonly transaction');
}
return await this.store.clear();
}
}
Loading

0 comments on commit f1db0b4

Please sign in to comment.