UBERF-8899: Fix Reconnect performance (#7597)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2025-01-07 23:21:27 +07:00
committed by GitHub
parent 1d836b73ab
commit a2cbc2a5fb
12 changed files with 106 additions and 73 deletions
+5
View File
@@ -162,6 +162,11 @@ export interface DBAdapterManager {
export interface PipelineContext {
workspace: WorkspaceIdWithUrl
lastTx?: string
lastHash?: string
hierarchy: Hierarchy
modelDb: ModelDb
branding: Branding | null
+1
View File
@@ -115,6 +115,7 @@ export class ModelMiddleware extends BaseMiddleware implements Middleware {
private setLastHash (hash: string): void {
this.lastHash = hash
this.context.lastHash = this.lastHash
this.lastHashResponse = Promise.resolve({
full: false,
hash,
+21 -1
View File
@@ -16,12 +16,16 @@
import core, {
DOMAIN_TRANSIENT,
DOMAIN_TX,
generateId,
TxProcessor,
WorkspaceEvent,
type Doc,
type MeasureContext,
type SessionData,
type Tx,
type TxCUD,
type TxResult
type TxResult,
type TxWorkspaceEvent
} from '@hcengineering/core'
import { PlatformError, unknownError } from '@hcengineering/platform'
import type { DBAdapterManager, Middleware, PipelineContext, TxMiddlewareResult } from '@hcengineering/server-core'
@@ -68,6 +72,22 @@ export class TxMiddleware extends BaseMiddleware implements Middleware {
txes: Array.from(new Set(txToStore.map((it) => it._class)))
}
)
// We need to remember last Tx Id in context, so it will be used during reconnect to track a requirement for refresh.
this.context.lastTx = txToStore[txToStore.length - 1]._id
// We need to deliver information to all clients so far.
const evt: TxWorkspaceEvent = {
_class: core.class.TxWorkspaceEvent,
_id: generateId(),
event: WorkspaceEvent.LastTx,
modifiedBy: core.account.System,
modifiedOn: Date.now(),
objectSpace: core.space.DerivedTx,
space: core.space.DerivedTx,
params: {
lastTx: this.context.lastTx
}
}
;(ctx.contextData as SessionData).broadcast.txes.push(evt)
}
if (txPromise !== undefined) {
await txPromise
+2
View File
@@ -46,6 +46,8 @@ export interface HelloResponse extends Response<any> {
binary: boolean
reconnect?: boolean
serverVersion: string
lastTx?: string
lastHash?: string // Last model hash
}
function replacer (key: string, value: any): any {
+8 -4
View File
@@ -990,7 +990,7 @@ class TSessionManager implements SessionManager {
return
}
if (request.id === -1 && request.method === 'hello') {
this.handleHello<S>(request, service, ctx, workspace, ws, requestCtx)
await this.handleHello<S>(request, service, ctx, workspace, ws, requestCtx)
return
}
if (request.id === -2 && request.method === 'forceClose') {
@@ -1053,14 +1053,14 @@ class TSessionManager implements SessionManager {
})
}
private handleHello<S extends Session>(
private async handleHello<S extends Session>(
request: Request<any>,
service: S,
ctx: MeasureContext<any>,
workspace: string,
ws: ConnectionSocket,
requestCtx: MeasureContext<any>
): void {
): Promise<void> {
const hello = request as HelloRequest
service.binaryMode = hello.binary ?? false
service.useCompression = hello.compression ?? false
@@ -1080,12 +1080,16 @@ class TSessionManager implements SessionManager {
if (reconnect) {
this.reconnectIds.delete(service.sessionId)
}
const pipeline =
service.workspace.pipeline instanceof Promise ? await service.workspace.pipeline : service.workspace.pipeline
const helloResponse: HelloResponse = {
id: -1,
result: 'hello',
binary: service.binaryMode,
reconnect,
serverVersion: this.serverVersion
serverVersion: this.serverVersion,
lastTx: pipeline.context.lastTx,
lastHash: pipeline.context.lastHash
}
ws.send(requestCtx, helloResponse, false, false)
}