mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-12 12:47:45 +02:00
UBERF-6374: Improve server logging and improve startup performance (#5210)
This commit is contained in:
@@ -128,7 +128,7 @@ class Connection implements ClientConnection {
|
||||
}
|
||||
}
|
||||
|
||||
delay = 1
|
||||
delay = 0
|
||||
pending: Promise<ClientSocket> | undefined
|
||||
|
||||
private async waitOpenConnection (): Promise<ClientSocket> {
|
||||
@@ -140,7 +140,7 @@ class Connection implements ClientConnection {
|
||||
}
|
||||
this.pending = this.openConnection()
|
||||
await this.pending
|
||||
this.delay = 5
|
||||
this.delay = 0
|
||||
return await this.pending
|
||||
} catch (err: any) {
|
||||
this.pending = undefined
|
||||
@@ -154,7 +154,7 @@ class Connection implements ClientConnection {
|
||||
setTimeout(() => {
|
||||
console.log(`delay ${this.delay} second`)
|
||||
resolve(null)
|
||||
if (this.delay !== 15) {
|
||||
if (this.delay < 5) {
|
||||
this.delay++
|
||||
}
|
||||
}, this.delay * SECOND)
|
||||
|
||||
@@ -18,6 +18,7 @@ import core, {
|
||||
AccountClient,
|
||||
ClientConnectEvent,
|
||||
LoadModelResponse,
|
||||
MeasureContext,
|
||||
Tx,
|
||||
TxHandler,
|
||||
TxPersistenceStore,
|
||||
@@ -37,6 +38,28 @@ import { connect } from './connection'
|
||||
|
||||
export { connect }
|
||||
|
||||
let dbRequest: IDBOpenDBRequest | undefined
|
||||
let dbPromise: Promise<IDBDatabase | undefined> = Promise.resolve(undefined)
|
||||
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const st = Date.now()
|
||||
dbPromise = new Promise<IDBDatabase>((resolve) => {
|
||||
dbRequest = indexedDB.open('model.db.persistence', 2)
|
||||
|
||||
dbRequest.onupgradeneeded = function () {
|
||||
const db = (dbRequest as IDBOpenDBRequest).result
|
||||
if (!db.objectStoreNames.contains('model')) {
|
||||
db.createObjectStore('model', { keyPath: 'id' })
|
||||
}
|
||||
}
|
||||
dbRequest.onsuccess = function () {
|
||||
const db = (dbRequest as IDBOpenDBRequest).result
|
||||
console.log('init DB complete', Date.now() - st)
|
||||
resolve(db)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => {
|
||||
return {
|
||||
@@ -46,7 +69,8 @@ export default async () => {
|
||||
endpoint: string,
|
||||
onUpgrade?: () => void,
|
||||
onUnauthorized?: () => void,
|
||||
onConnect?: (event: ClientConnectEvent) => void
|
||||
onConnect?: (event: ClientConnectEvent) => void,
|
||||
ctx?: MeasureContext
|
||||
): Promise<AccountClient> => {
|
||||
const filterModel = getMetadata(clientPlugin.metadata.FilterModel) ?? false
|
||||
|
||||
@@ -75,7 +99,8 @@ export default async () => {
|
||||
return connect(url.href, upgradeHandler, onUpgrade, onUnauthorized, onConnect)
|
||||
},
|
||||
filterModel ? [...getPlugins(), ...(getMetadata(clientPlugin.metadata.ExtraPlugins) ?? [])] : undefined,
|
||||
createModelPersistence(getWSFromToken(token))
|
||||
createModelPersistence(getWSFromToken(token)),
|
||||
ctx
|
||||
)
|
||||
// Check if we had dev hook for client.
|
||||
client = hookClient(client)
|
||||
@@ -90,25 +115,6 @@ function createModelPersistence (workspace: string): TxPersistenceStore | undefi
|
||||
return overrideStore
|
||||
}
|
||||
|
||||
let dbRequest: IDBOpenDBRequest | undefined
|
||||
let dbPromise: Promise<IDBDatabase | undefined> = Promise.resolve(undefined)
|
||||
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
dbPromise = new Promise<IDBDatabase>((resolve) => {
|
||||
dbRequest = indexedDB.open('model.db.persistence', 2)
|
||||
|
||||
dbRequest.onupgradeneeded = function () {
|
||||
const db = (dbRequest as IDBOpenDBRequest).result
|
||||
if (!db.objectStoreNames.contains('model')) {
|
||||
db.createObjectStore('model', { keyPath: 'id' })
|
||||
}
|
||||
}
|
||||
dbRequest.onsuccess = function () {
|
||||
const db = (dbRequest as IDBOpenDBRequest).result
|
||||
resolve(db)
|
||||
}
|
||||
})
|
||||
}
|
||||
return {
|
||||
load: async () => {
|
||||
const db = await dbPromise
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { AccountClient, ClientConnectEvent, TxPersistenceStore } from '@hcengineering/core'
|
||||
import type { AccountClient, ClientConnectEvent, MeasureContext, TxPersistenceStore } from '@hcengineering/core'
|
||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||
import { Metadata, plugin } from '@hcengineering/platform'
|
||||
|
||||
@@ -66,7 +66,8 @@ export type ClientFactory = (
|
||||
endpoint: string,
|
||||
onUpgrade?: () => void,
|
||||
onUnauthorized?: () => void,
|
||||
onConnect?: (event: ClientConnectEvent) => void
|
||||
onConnect?: (event: ClientConnectEvent) => void,
|
||||
ctx?: MeasureContext
|
||||
) => Promise<AccountClient>
|
||||
|
||||
export default plugin(clientId, {
|
||||
|
||||
@@ -3,6 +3,8 @@ import client from '@hcengineering/client'
|
||||
import core, {
|
||||
ClientConnectEvent,
|
||||
getCurrentAccount,
|
||||
MeasureMetricsContext,
|
||||
metricsToString,
|
||||
setCurrentAccount,
|
||||
versionToString,
|
||||
type AccountClient,
|
||||
@@ -41,6 +43,7 @@ export async function disconnect (): Promise<void> {
|
||||
}
|
||||
|
||||
export async function connect (title: string): Promise<Client | undefined> {
|
||||
const ctx = new MeasureMetricsContext('connect', {})
|
||||
const loc = getCurrentLocation()
|
||||
const ws = loc.path[1]
|
||||
if (ws === undefined) {
|
||||
@@ -62,7 +65,7 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
let token = tokens[ws]
|
||||
if (token === undefined && getMetadata(presentation.metadata.Token) !== undefined) {
|
||||
const selectWorkspace = await getResource(login.function.SelectWorkspace)
|
||||
const loginInfo = (await selectWorkspace(ws))[1]
|
||||
const loginInfo = await ctx.with('select-workspace', {}, async () => (await selectWorkspace(ws))[1])
|
||||
if (loginInfo !== undefined) {
|
||||
tokens[ws] = loginInfo.token
|
||||
token = loginInfo.token
|
||||
@@ -88,8 +91,12 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
if (_token !== token && _client !== undefined) {
|
||||
// We need to flush all data from memory
|
||||
await purgeClient()
|
||||
await _client.close()
|
||||
await ctx.with('purge-client', {}, async () => {
|
||||
await purgeClient()
|
||||
})
|
||||
await ctx.with('close previous client', {}, async () => {
|
||||
await _client?.close()
|
||||
})
|
||||
_client = undefined
|
||||
tokenChanged = true
|
||||
}
|
||||
@@ -104,63 +111,79 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
serverEndpoint = serverEndpoint.substring(0, serverEndpoint.length - 1)
|
||||
}
|
||||
const clientFactory = await getResource(client.function.GetClient)
|
||||
_client = await clientFactory(
|
||||
token,
|
||||
endpoint,
|
||||
() => {
|
||||
location.reload()
|
||||
},
|
||||
() => {
|
||||
clearMetadata(ws)
|
||||
navigate({
|
||||
path: [loginId],
|
||||
query: {}
|
||||
})
|
||||
},
|
||||
// We need to refresh all active live queries and clear old queries.
|
||||
(event: ClientConnectEvent) => {
|
||||
console.log('WorkbenchClient: onConnect', event)
|
||||
try {
|
||||
if ((_clientSet && event === ClientConnectEvent.Connected) || event === ClientConnectEvent.Refresh) {
|
||||
void refreshClient(tokenChanged)
|
||||
tokenChanged = false
|
||||
}
|
||||
|
||||
if (event === ClientConnectEvent.Upgraded) {
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
void (async () => {
|
||||
if (_client !== undefined) {
|
||||
const newVersion = await _client.findOne<Version>(core.class.Version, {})
|
||||
console.log('Reconnect Model version', newVersion)
|
||||
|
||||
const currentVersionStr = versionToString(version as Version)
|
||||
const reconnectVersionStr = versionToString(newVersion as Version)
|
||||
|
||||
if (currentVersionStr !== reconnectVersionStr) {
|
||||
// It seems upgrade happened
|
||||
// location.reload()
|
||||
versionError = `${currentVersionStr} != ${reconnectVersionStr}`
|
||||
const newClient = await ctx.with(
|
||||
'create-client',
|
||||
{},
|
||||
async (ctx) =>
|
||||
await clientFactory(
|
||||
token,
|
||||
endpoint,
|
||||
() => {
|
||||
location.reload()
|
||||
},
|
||||
() => {
|
||||
clearMetadata(ws)
|
||||
navigate({
|
||||
path: [loginId],
|
||||
query: {}
|
||||
})
|
||||
},
|
||||
// We need to refresh all active live queries and clear old queries.
|
||||
(event: ClientConnectEvent) => {
|
||||
console.log('WorkbenchClient: onConnect', event)
|
||||
try {
|
||||
if ((_clientSet && event === ClientConnectEvent.Connected) || event === ClientConnectEvent.Refresh) {
|
||||
void ctx.with('refresh client', {}, async () => {
|
||||
await refreshClient(tokenChanged)
|
||||
})
|
||||
tokenChanged = false
|
||||
}
|
||||
const serverVersion: { version: string } = await (
|
||||
await fetch(serverEndpoint + '/api/v1/version', {})
|
||||
).json()
|
||||
|
||||
console.log('Server version', serverVersion.version)
|
||||
if (serverVersion.version !== '' && serverVersion.version !== currentVersionStr) {
|
||||
versionError = `${currentVersionStr} => ${serverVersion.version}`
|
||||
if (event === ClientConnectEvent.Upgraded) {
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
void (async () => {
|
||||
if (_client !== undefined) {
|
||||
const newVersion = await ctx.with(
|
||||
'find-version',
|
||||
{},
|
||||
async () => await newClient.findOne<Version>(core.class.Version, {})
|
||||
)
|
||||
console.log('Reconnect Model version', newVersion)
|
||||
|
||||
const currentVersionStr = versionToString(version as Version)
|
||||
const reconnectVersionStr = versionToString(newVersion as Version)
|
||||
|
||||
if (currentVersionStr !== reconnectVersionStr) {
|
||||
// It seems upgrade happened
|
||||
// location.reload()
|
||||
versionError = `${currentVersionStr} != ${reconnectVersionStr}`
|
||||
}
|
||||
const serverVersion: { version: string } = await ctx.with(
|
||||
'fetch-server-version',
|
||||
{},
|
||||
async () => await (await fetch(serverEndpoint + '/api/v1/version', {})).json()
|
||||
)
|
||||
|
||||
console.log('Server version', serverVersion.version)
|
||||
if (serverVersion.version !== '' && serverVersion.version !== currentVersionStr) {
|
||||
versionError = `${currentVersionStr} => ${serverVersion.version}`
|
||||
}
|
||||
}
|
||||
})()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
})()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
},
|
||||
ctx
|
||||
)
|
||||
)
|
||||
|
||||
_client = newClient
|
||||
console.log('logging in as', email)
|
||||
|
||||
const me = await _client?.getAccount()
|
||||
const me = await ctx.with('get-account', {}, async () => await newClient.getAccount())
|
||||
if (me !== undefined) {
|
||||
Analytics.setUser(me.email)
|
||||
Analytics.setTag('workspace', ws)
|
||||
@@ -176,11 +199,18 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
// Update on connect, so it will be triggered
|
||||
_clientSet = true
|
||||
await setClient(_client)
|
||||
const client = _client
|
||||
await ctx.with('set-client', {}, async () => {
|
||||
await setClient(client)
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
version = await _client.findOne<Version>(core.class.Version, {})
|
||||
version = await ctx.with(
|
||||
'find-model-version',
|
||||
{},
|
||||
async () => await newClient.findOne<Version>(core.class.Version, {})
|
||||
)
|
||||
console.log('Model version', version)
|
||||
|
||||
const requiredVersion = getMetadata(presentation.metadata.RequiredVersion)
|
||||
@@ -195,7 +225,11 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
}
|
||||
|
||||
try {
|
||||
const serverVersion: { version: string } = await (await fetch(serverEndpoint + '/api/v1/version', {})).json()
|
||||
const serverVersion: { version: string } = await ctx.with(
|
||||
'find-server-version',
|
||||
{},
|
||||
async () => await (await fetch(serverEndpoint + '/api/v1/version', {})).json()
|
||||
)
|
||||
|
||||
console.log('Server version', serverVersion.version)
|
||||
if (
|
||||
@@ -223,10 +257,14 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
// Update window title
|
||||
document.title = [ws, title].filter((it) => it).join(' - ')
|
||||
_clientSet = true
|
||||
await setClient(_client)
|
||||
await broadcastEvent(plugin.event.NotifyConnection, getCurrentAccount())
|
||||
|
||||
return _client
|
||||
await ctx.with('set-client', {}, async () => {
|
||||
await setClient(newClient)
|
||||
})
|
||||
await ctx.with('broadcast-connected', {}, async () => {
|
||||
await broadcastEvent(plugin.event.NotifyConnection, getCurrentAccount())
|
||||
})
|
||||
console.log(metricsToString(ctx.metrics, 'connect', 50))
|
||||
return newClient
|
||||
}
|
||||
|
||||
function clearMetadata (ws: string): void {
|
||||
|
||||
Reference in New Issue
Block a user