feat: sync client versioning (#5645)

after this pr, server will only accept client that have some major version
the client version <0.12 will be rejected by the server, >= 0.12 can receive outdated messages and notify users
This commit is contained in:
DarkSky
2024-02-05 08:43:50 +00:00
parent 5ca0d65241
commit 25e8a2a22f
15 changed files with 144 additions and 143 deletions

View File

@@ -195,6 +195,14 @@ const useSyncEngineSyncProgress = () => {
`Syncing with AFFiNE Cloud` +
(progress ? ` (${Math.floor(progress * 100)}%)` : '')
);
} else if (
syncEngineStatus &&
syncEngineStatus.step < SyncEngineStep.Syncing
) {
return (
syncEngineStatus.error ||
'Disconnected, please check your network connection'
);
}
if (syncEngineStatus.retrying) {
return 'Sync disconnected due to unexpected issues, reconnecting.';
@@ -227,7 +235,7 @@ const useSyncEngineSyncProgress = () => {
message: content,
icon:
currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD ? (
!isOnline ? (
!isOnline || syncEngineStatus?.error ? (
<OfflineStatus />
) : (
<CloudWorkspaceSyncStatus />

View File

@@ -1,5 +1,5 @@
import { DebugLogger } from '@affine/debug';
import type { AwarenessProvider } from '@toeverything/infra';
import type { AwarenessProvider, RejectByVersion } from '@toeverything/infra';
import {
applyAwarenessUpdate,
type Awareness,
@@ -33,6 +33,7 @@ export class AffineCloudAwarenessProvider implements AwarenessProvider {
window.addEventListener('beforeunload', this.windowBeforeUnloadHandler);
this.socket.on('connect', () => this.handleConnect());
this.socket.on('server-version-rejected', this.handleReject);
if (this.socket.connected) {
this.handleConnect();
@@ -40,6 +41,7 @@ export class AffineCloudAwarenessProvider implements AwarenessProvider {
this.socket.connect();
}
}
disconnect(): void {
removeAwarenessStates(
this.awareness,
@@ -54,6 +56,7 @@ export class AffineCloudAwarenessProvider implements AwarenessProvider {
this.newClientAwarenessInitHandler
);
this.socket.off('connect', this.handleConnect);
this.socket.off('server-version-rejected', this.handleReject);
window.removeEventListener('unload', this.windowBeforeUnloadHandler);
}
@@ -117,7 +120,16 @@ export class AffineCloudAwarenessProvider implements AwarenessProvider {
};
handleConnect = () => {
this.socket.emit('client-handshake-awareness', this.workspaceId);
this.socket.emit('client-handshake-awareness', {
workspaceId: this.workspaceId,
version: runtimeConfig.appVersion,
});
this.socket.emit('awareness-init', this.workspaceId);
};
handleReject = (_msg: RejectByVersion) => {
this.socket.off('server-version-rejected', this.handleReject);
this.disconnect();
this.socket.disconnect();
};
}

View File

@@ -1,6 +1,10 @@
import { DebugLogger } from '@affine/debug';
import { fetchWithTraceReport } from '@affine/graphql';
import { type SyncStorage } from '@toeverything/infra';
import {
type RejectByVersion,
type SyncErrorMessage,
type SyncStorage,
} from '@toeverything/infra';
import type { CleanupService } from '@toeverything/infra/lifecycle';
import { getIoManager } from '../utils/affine-io';
@@ -15,14 +19,17 @@ export class AffineSyncStorage implements SyncStorage {
socket = getIoManager().socket('/');
errorMessage?: SyncErrorMessage;
constructor(
private readonly workspaceId: string,
cleanupService: CleanupService
) {
this.socket.on('connect', this.handleConnect);
this.socket.on('server-version-rejected', this.handleReject);
if (this.socket.connected) {
this.socket.emit('client-handshake-sync', this.workspaceId);
this.handleConnect();
} else {
this.socket.connect();
}
@@ -33,7 +40,17 @@ export class AffineSyncStorage implements SyncStorage {
}
handleConnect = () => {
this.socket.emit('client-handshake-sync', this.workspaceId);
this.socket.emit('client-handshake-sync', {
workspaceId: this.workspaceId,
version: runtimeConfig.appVersion,
});
};
handleReject = (message: RejectByVersion) => {
this.socket.off('server-version-rejected', this.handleReject);
this.cleanup();
this.socket.disconnect();
this.errorMessage = { type: 'outdated', message };
};
async pull(