UBERF-9137: Fix Support for suspended installations (#7667)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2025-01-15 23:23:23 +07:00
committed by GitHub
parent 0c6feb646e
commit c8dde57123
24 changed files with 435 additions and 336 deletions
+72 -33
View File
@@ -87,6 +87,8 @@ class RequestPromise {
chunks?: { index: number, data: FindResult<any> }[]
}
const globalRPCHandler: RPCHandler = new RPCHandler()
class Connection implements ClientConnection {
private websocket: ClientSocket | null = null
binaryMode = false
@@ -115,7 +117,7 @@ class Connection implements ClientConnection {
onConnect?: (event: ClientConnectEvent, lastTx: string | undefined, data: any) => Promise<void>
rpcHandler = new RPCHandler()
rpcHandler: RPCHandler
lastHash?: string
@@ -145,6 +147,7 @@ class Connection implements ClientConnection {
} else {
this.sessionId = generateId()
}
this.rpcHandler = opt?.useGlobalRPCHandler === true ? globalRPCHandler : new RPCHandler()
this.onConnect = opt?.onConnect
@@ -187,6 +190,8 @@ class Connection implements ClientConnection {
this.pingResponse = Date.now()
}
}
}).catch((err) => {
this.ctx.error('failed to send msg', { err })
})
} else {
clearInterval(this.interval)
@@ -336,7 +341,9 @@ class Connection implements ClientConnection {
helloResp.reconnect === true ? ClientConnectEvent.Reconnected : ClientConnectEvent.Connected,
helloResp.lastTx,
this.sessionId
)
)?.catch((err) => {
this.ctx.error('failed to call onConnect', { err })
})
this.schedulePing(socketId)
return
} else {
@@ -345,7 +352,9 @@ class Connection implements ClientConnection {
return
}
if (resp.result === pingConst) {
void this.sendRequest({ method: pingConst, params: [] })
void this.sendRequest({ method: pingConst, params: [] }).catch((err) => {
this.ctx.error('failed to send ping', { err })
})
return
}
if (resp.id !== undefined) {
@@ -416,14 +425,21 @@ class Connection implements ClientConnection {
promise.reject(new PlatformError(resp.error))
} else {
if (request?.handleResult !== undefined) {
void request.handleResult(resp.result).then(() => {
promise.resolve(resp.result)
})
void request
.handleResult(resp.result)
.then(() => {
promise.resolve(resp.result)
})
.catch((err) => {
this.ctx.error('failed to handleResult', { err })
})
} else {
promise.resolve(resp.result)
}
}
void broadcastEvent(client.event.NetworkRequests, this.requests.size)
void broadcastEvent(client.event.NetworkRequests, this.requests.size).catch((err) => {
this.ctx.error('failed to broadcast', { err })
})
} else {
const txArr = Array.isArray(resp.result) ? (resp.result as Tx[]) : [resp.result as Tx]
@@ -437,10 +453,14 @@ class Connection implements ClientConnection {
this.handler(...txArr)
clearTimeout(this.incomingTimer)
void broadcastEvent(client.event.NetworkRequests, this.requests.size + 1)
void broadcastEvent(client.event.NetworkRequests, this.requests.size + 1).catch((err) => {
this.ctx.error('failed to broadcast', { err })
})
this.incomingTimer = setTimeout(() => {
void broadcastEvent(client.event.NetworkRequests, this.requests.size)
void broadcastEvent(client.event.NetworkRequests, this.requests.size).catch((err) => {
this.ctx.error('failed to broadcast', { err })
})
}, 500)
}
}
@@ -476,7 +496,9 @@ class Connection implements ClientConnection {
this.dialTimer = setTimeout(() => {
this.dialTimer = null
if (!opened && !this.closed) {
void this.opt?.onDialTimeout?.()
void this.opt?.onDialTimeout?.()?.catch((err) => {
this.ctx.error('failed to handle dial timeout', { err })
})
this.scheduleOpen(this.ctx, true)
}
}, dialTimeout)
@@ -494,7 +516,9 @@ class Connection implements ClientConnection {
return
}
if (event.data === pingConst) {
void this.sendRequest({ method: pingConst, params: [] })
void this.sendRequest({ method: pingConst, params: [] }).catch((err) => {
this.ctx.error('failed to send ping', { err })
})
return
}
if (
@@ -503,7 +527,9 @@ class Connection implements ClientConnection {
) {
const text = new TextDecoder().decode(event.data)
if (text === pingConst) {
void this.sendRequest({ method: pingConst, params: [] })
void this.sendRequest({ method: pingConst, params: [] }).catch((err) => {
this.ctx.error('failed to send ping', { err })
})
}
if (text === pongConst) {
this.pingResponse = Date.now()
@@ -511,27 +537,32 @@ class Connection implements ClientConnection {
return
}
if (event.data instanceof Blob) {
void event.data.arrayBuffer().then((data) => {
if (this.compressionMode && this.helloReceived) {
void event.data
.arrayBuffer()
.then((data) => {
if (this.compressionMode && this.helloReceived) {
try {
data = uncompress(data)
} catch (err: any) {
// Ignore
console.error(err)
}
}
try {
data = uncompress(data)
const resp = this.rpcHandler.readResponse<any>(data, this.binaryMode)
this.handleMsg(socketId, resp)
} catch (err: any) {
// Ignore
console.error(err)
if (!this.helloReceived) {
// Just error and ignore for now.
console.error(err)
} else {
throw err
}
}
}
try {
const resp = this.rpcHandler.readResponse<any>(data, this.binaryMode)
this.handleMsg(socketId, resp)
} catch (err: any) {
if (!this.helloReceived) {
// Just error and ignore for now.
console.error(err)
} else {
throw err
}
}
})
})
.catch((err) => {
this.ctx.error('failed to decode array buffer', { err })
})
} else {
let data = event.data
if (this.compressionMode && this.helloReceived) {
@@ -561,7 +592,9 @@ class Connection implements ClientConnection {
return
}
// console.log('client websocket closed', socketId, ev?.reason)
void broadcastEvent(client.event.NetworkRequests, -1)
void broadcastEvent(client.event.NetworkRequests, -1).catch((err) => {
this.ctx.error('failed broadcast', { err })
})
this.scheduleOpen(this.ctx, true)
}
wsocket.onopen = () => {
@@ -591,7 +624,9 @@ class Connection implements ClientConnection {
if (opened) {
console.error('client websocket error:', socketId, this.url, this.workspace, this.email)
}
void broadcastEvent(client.event.NetworkRequests, -1)
void broadcastEvent(client.event.NetworkRequests, -1).catch((err) => {
this.ctx.error('failed to broadcast', { err })
})
}
}
@@ -669,7 +704,11 @@ class Connection implements ClientConnection {
ctx.withSync('send-data', {}, () => {
sendData()
})
void ctx.with('broadcast-event', {}, () => broadcastEvent(client.event.NetworkRequests, this.requests.size))
void ctx
.with('broadcast-event', {}, () => broadcastEvent(client.event.NetworkRequests, this.requests.size))
.catch((err) => {
this.ctx.error('failed to broadcast', { err })
})
if (data.method !== pingConst) {
return await promise.promise
}
+13 -2
View File
@@ -133,7 +133,7 @@ export default async () => {
return await Promise.resolve(clientConnection)
}
const modelFilter: ModelFilter = async (txes) => {
const modelFilter: ModelFilter = (txes) => {
if (filterModel === 'client') {
return returnClientTxes(txes)
}
@@ -177,7 +177,18 @@ function returnClientTxes (txes: Tx[]): Tx[] {
'templates:class:TemplateField' as Ref<Class<Doc>>,
'activity:class:DocUpdateMessageViewlet' as Ref<Class<Doc>>,
'core:class:PluginConfiguration' as Ref<Class<Doc>>,
'core:class:DomainIndexConfiguration' as Ref<Class<Doc>>
'core:class:DomainIndexConfiguration' as Ref<Class<Doc>>,
'view:class:ViewletDescriptor' as Ref<Class<Doc>>,
'presentation:class:ComponentPointExtension' as Ref<Class<Doc>>,
'activity:class:ActivityMessagesFilter' as Ref<Class<Doc>>,
'view:class:ActionCategory' as Ref<Class<Doc>>,
'activity:class:ActivityExtension' as Ref<Class<Doc>>,
'chunter:class:ChatMessageViewlet' as Ref<Class<Doc>>,
'activity:class:ActivityMessageControl' as Ref<Class<Doc>>,
'notification:class:ActivityNotificationViewlet' as Ref<Class<Doc>>,
'setting:class:SettingsCategory' as Ref<Class<Doc>>,
'setting:class:WorkspaceSettingCategory' as Ref<Class<Doc>>,
'notification:class:NotificationProvider' as Ref<Class<Doc>>
])
const result = pluginFilterTx(excludedPlugins, configs, txes).filter((tx) => {