diff --git a/plugins/client-resources/src/connection.ts b/plugins/client-resources/src/connection.ts index 9e6485ab82..3d841613d8 100644 --- a/plugins/client-resources/src/connection.ts +++ b/plugins/client-resources/src/connection.ts @@ -89,8 +89,6 @@ class Connection implements ClientConnection { readonly onConnect?: (event: ClientConnectEvent) => Promise ) { this.interval = setInterval(() => { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - if (this.pingResponse !== 0 && Date.now() - this.pingResponse > hangTimeout) { // No ping response from server. const s = this.websocket @@ -108,6 +106,7 @@ class Connection implements ClientConnection { this.websocket = null } + // eslint-disable-next-line @typescript-eslint/no-floating-promises void this.sendRequest({ method: 'ping', params: [] }).then(() => { this.pingResponse = Date.now() }) @@ -229,6 +228,10 @@ class Connection implements ClientConnection { ) return } + if (resp.result === 'ping') { + void this.sendRequest({ method: 'ping', params: [] }) + return + } if (resp.id !== undefined) { const promise = this.requests.get(resp.id) if (promise === undefined) { diff --git a/server/ws/src/client.ts b/server/ws/src/client.ts index 0fb23fd35b..35c0716812 100644 --- a/server/ws/src/client.ts +++ b/server/ws/src/client.ts @@ -53,6 +53,7 @@ export class ClientSession implements Session { useCompression: boolean = true useBroadcast: boolean = false sessionId = '' + lastRequest = 0 total: StatisticsElement = { find: 0, tx: 0 } current: StatisticsElement = { find: 0, tx: 0 } @@ -75,6 +76,7 @@ export class ClientSession implements Session { async ping (): Promise { // console.log('ping') + this.lastRequest = Date.now() return 'pong!' } @@ -120,6 +122,7 @@ export class ClientSession implements Session { query: DocumentQuery, options?: FindOptions ): Promise> { + this.lastRequest = Date.now() this.total.find++ this.current.find++ const context = ctx as SessionContext @@ -129,6 +132,7 @@ export class ClientSession implements Session { } async searchFulltext (ctx: MeasureContext, query: SearchQuery, options: SearchOptions): Promise { + this.lastRequest = Date.now() const context = ctx as SessionContext context.userEmail = this.token.email context.admin = this.token.extra?.admin === 'true' @@ -136,6 +140,7 @@ export class ClientSession implements Session { } async tx (ctx: MeasureContext, tx: Tx): Promise { + this.lastRequest = Date.now() this.total.tx++ this.current.tx++ const context = ctx as SessionContext diff --git a/server/ws/src/server.ts b/server/ws/src/server.ts index fa4054478d..9f3b4df841 100644 --- a/server/ws/src/server.ts +++ b/server/ws/src/server.ts @@ -142,10 +142,24 @@ class TSessionManager implements SessionManager { s[1].session.current = { find: 0, tx: 0 } } - for (const r of s[1].session.requests.values()) { - const ed = Date.now() + const now = Date.now() + const diff = now - s[1].session.lastRequest + if (diff > 60000) { + console.log('session hang, closing...', h[0], s[1].session.getUser()) + void this.close(s[1].socket, h[1].workspaceId, 1001, 'CLIENT_HANGOUT') + continue + } + if (diff > 20000 && this.ticks % 10 === 0) { + void s[1].socket.send( + h[1].context, + { result: 'ping' }, + s[1].session.binaryResponseMode, + s[1].session.useCompression + ) + } - if (ed - r.start > 30000) { + for (const r of s[1].session.requests.values()) { + if (now - r.start > 30000) { console.log(h[0], 'request hang found, 30sec', h[0], s[1].session.getUser(), r.params) } } @@ -262,6 +276,7 @@ class TSessionManager implements SessionManager { } const session = this.createSession(token, pipeline) + session.sessionId = sessionId !== undefined && (sessionId ?? '').trim().length > 0 ? sessionId : generateId() session.sessionInstanceId = generateId() this.sessions.set(ws.id, { session, socket: ws }) @@ -367,6 +382,7 @@ class TSessionManager implements SessionManager { ), sessions: new Map(), upgrade, + workspaceId: token.workspace, workspaceName } if (LOGGING_ENABLED) console.time(workspaceName) diff --git a/server/ws/src/types.ts b/server/ws/src/types.ts index a9a4b34430..8360eaf045 100644 --- a/server/ws/src/types.ts +++ b/server/ws/src/types.ts @@ -62,6 +62,8 @@ export interface Session { mins5: StatisticsElement measureCtx?: { ctx: MeasureContext, time: number } + + lastRequest: number } /** @@ -117,6 +119,7 @@ export interface Workspace { upgrade: boolean closing?: Promise + workspaceId: WorkspaceId workspaceName: string }