mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-07 00:09:34 +00:00
Race safe user status (#5300)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
9419278973
commit
64e0431a72
@ -64,6 +64,7 @@ export interface Timeouts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TSessionManager implements SessionManager {
|
class TSessionManager implements SessionManager {
|
||||||
|
private readonly statusPromises = new Map<string, Promise<void>>()
|
||||||
readonly workspaces = new Map<string, Workspace>()
|
readonly workspaces = new Map<string, Workspace>()
|
||||||
checkInterval: any
|
checkInterval: any
|
||||||
|
|
||||||
@ -295,7 +296,7 @@ class TSessionManager implements SessionManager {
|
|||||||
workspace.sessions.set(session.sessionId, { session, socket: ws })
|
workspace.sessions.set(session.sessionId, { session, socket: ws })
|
||||||
|
|
||||||
// We do not need to wait for set-status, just return session to client
|
// We do not need to wait for set-status, just return session to client
|
||||||
void ctx.with('set-status', {}, (ctx) => this.setStatus(ctx, session, true))
|
void ctx.with('set-status', {}, (ctx) => this.trySetStatus(ctx, session, true))
|
||||||
|
|
||||||
if (this.timeMinutes > 0) {
|
if (this.timeMinutes > 0) {
|
||||||
void ws.send(
|
void ws.send(
|
||||||
@ -420,6 +421,17 @@ class TSessionManager implements SessionManager {
|
|||||||
return workspace
|
return workspace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async trySetStatus (ctx: MeasureContext, session: Session, online: boolean): Promise<void> {
|
||||||
|
const current = this.statusPromises.get(session.getUser())
|
||||||
|
if (current !== undefined) {
|
||||||
|
await current
|
||||||
|
}
|
||||||
|
const promise = this.setStatus(ctx, session, online)
|
||||||
|
this.statusPromises.set(session.getUser(), promise)
|
||||||
|
await promise
|
||||||
|
this.statusPromises.delete(session.getUser())
|
||||||
|
}
|
||||||
|
|
||||||
private async setStatus (ctx: MeasureContext, session: Session, online: boolean): Promise<void> {
|
private async setStatus (ctx: MeasureContext, session: Session, online: boolean): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const user = (
|
const user = (
|
||||||
@ -475,7 +487,7 @@ class TSessionManager implements SessionManager {
|
|||||||
const user = sessionRef.session.getUser()
|
const user = sessionRef.session.getUser()
|
||||||
const another = Array.from(workspace.sessions.values()).findIndex((p) => p.session.getUser() === user)
|
const another = Array.from(workspace.sessions.values()).findIndex((p) => p.session.getUser() === user)
|
||||||
if (another === -1) {
|
if (another === -1) {
|
||||||
await this.setStatus(workspace.context, sessionRef.session, false)
|
await this.trySetStatus(workspace.context, sessionRef.session, false)
|
||||||
}
|
}
|
||||||
if (!workspace.upgrade) {
|
if (!workspace.upgrade) {
|
||||||
// Wait some time for new client to appear before closing workspace.
|
// Wait some time for new client to appear before closing workspace.
|
||||||
@ -513,7 +525,7 @@ class TSessionManager implements SessionManager {
|
|||||||
await this.sendUpgrade(workspace.context, webSocket, s.binaryResponseMode)
|
await this.sendUpgrade(workspace.context, webSocket, s.binaryResponseMode)
|
||||||
}
|
}
|
||||||
webSocket.close()
|
webSocket.close()
|
||||||
await this.setStatus(workspace.context, s, false)
|
await this.trySetStatus(workspace.context, s, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOGGING_ENABLED) {
|
if (LOGGING_ENABLED) {
|
||||||
|
Loading…
Reference in New Issue
Block a user