Ping from server (#5039)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-03-22 13:56:17 +05:00 committed by GitHub
parent fe5d787250
commit 3d2b60ac99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 5 deletions

View File

@ -89,8 +89,6 @@ class Connection implements ClientConnection {
readonly onConnect?: (event: ClientConnectEvent) => Promise<void>
) {
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) {

View File

@ -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<string> {
// console.log('ping')
this.lastRequest = Date.now()
return 'pong!'
}
@ -120,6 +122,7 @@ export class ClientSession implements Session {
query: DocumentQuery<T>,
options?: FindOptions<T>
): Promise<FindResult<T>> {
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<SearchResult> {
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<TxResult> {
this.lastRequest = Date.now()
this.total.tx++
this.current.tx++
const context = ctx as SessionContext

View File

@ -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)

View File

@ -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<void>
workspaceId: WorkspaceId
workspaceName: string
}