mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 03:40:48 +00:00
TSK-1065: Check model version (#2916)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
33db59a5e2
commit
b699096e22
@ -337,6 +337,13 @@ export interface Version extends Doc {
|
||||
patch: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function versionToString (version: Version): string {
|
||||
return `${version?.major}.${version?.minor}.${version?.patch}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Blob data from s3 storage
|
||||
* @public
|
||||
|
@ -15,8 +15,7 @@
|
||||
|
||||
import { Plugin } from '@hcengineering/platform'
|
||||
import { BackupClient, DocChunk } from './backup'
|
||||
import type { Class, Doc, Domain, PluginConfiguration, Ref } from './classes'
|
||||
import { DOMAIN_MODEL } from './classes'
|
||||
import { Class, DOMAIN_MODEL, Doc, Domain, PluginConfiguration, Ref } from './classes'
|
||||
import core from './component'
|
||||
import { Hierarchy } from './hierarchy'
|
||||
import { ModelDb } from './memdb'
|
||||
@ -52,7 +51,7 @@ export interface Client extends Storage {
|
||||
*/
|
||||
export interface ClientConnection extends Storage, BackupClient {
|
||||
close: () => Promise<void>
|
||||
onConnect?: () => Promise<void>
|
||||
onConnect?: (apply: boolean) => Promise<void>
|
||||
}
|
||||
|
||||
class ClientImpl implements Client, BackupClient {
|
||||
@ -189,7 +188,7 @@ export async function createClient (
|
||||
}
|
||||
txBuffer = undefined
|
||||
|
||||
const oldOnConnect: (() => void) | undefined = conn.onConnect
|
||||
const oldOnConnect: ((apply: boolean) => void) | undefined = conn.onConnect
|
||||
conn.onConnect = async () => {
|
||||
// Find all new transactions and apply
|
||||
await loadModel(conn, loadedTxIds, allowedPlugins, configs, hierarchy, model)
|
||||
@ -205,9 +204,10 @@ export async function createClient (
|
||||
for (const tx of atxes) {
|
||||
txHandler(tx)
|
||||
}
|
||||
await oldOnConnect?.(true)
|
||||
} else {
|
||||
// We need to trigger full refresh on queries, etc.
|
||||
await oldOnConnect?.()
|
||||
await oldOnConnect?.(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class Connection implements ClientConnection {
|
||||
private readonly handler: TxHandler,
|
||||
private readonly onUpgrade?: () => void,
|
||||
private readonly onUnauthorized?: () => void,
|
||||
readonly onConnect?: () => Promise<void>
|
||||
readonly onConnect?: (apply: boolean) => Promise<void>
|
||||
) {
|
||||
console.log('connection created')
|
||||
this.interval = setInterval(() => {
|
||||
@ -151,7 +151,7 @@ class Connection implements ClientConnection {
|
||||
v.reconnect?.()
|
||||
}
|
||||
resolve(websocket)
|
||||
void this.onConnect?.()
|
||||
void this.onConnect?.(false)
|
||||
|
||||
return
|
||||
}
|
||||
@ -307,9 +307,9 @@ export async function connect (
|
||||
handler: TxHandler,
|
||||
onUpgrade?: () => void,
|
||||
onUnauthorized?: () => void,
|
||||
onConnect?: () => void
|
||||
onConnect?: (apply: boolean) => void
|
||||
): Promise<ClientConnection> {
|
||||
return new Connection(url, handler, onUpgrade, onUnauthorized, async () => {
|
||||
onConnect?.()
|
||||
return new Connection(url, handler, onUpgrade, onUnauthorized, async (apply) => {
|
||||
onConnect?.(apply)
|
||||
})
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import clientPlugin from '@hcengineering/client'
|
||||
import { Client, createClient, TxHandler } from '@hcengineering/core'
|
||||
import core, { Client, createClient, TxHandler, TxWorkspaceEvent, WorkspaceEvent } from '@hcengineering/core'
|
||||
import { getMetadata, getPlugins, getResource } from '@hcengineering/platform'
|
||||
import { connect } from './connection'
|
||||
|
||||
@ -29,7 +29,7 @@ export default async () => {
|
||||
endpoint: string,
|
||||
onUpgrade?: () => void,
|
||||
onUnauthorized?: () => void,
|
||||
onConnect?: () => void
|
||||
onConnect?: (apply: boolean) => void
|
||||
): Promise<Client> => {
|
||||
const filterModel = getMetadata(clientPlugin.metadata.FilterModel) ?? false
|
||||
|
||||
@ -37,7 +37,16 @@ export default async () => {
|
||||
(handler: TxHandler) => {
|
||||
const url = new URL(`/${token}`, endpoint)
|
||||
console.log('connecting to', url.href)
|
||||
return connect(url.href, handler, onUpgrade, onUnauthorized, onConnect)
|
||||
const upgradeHandler: TxHandler = (tx) => {
|
||||
if (tx._class === core.class.TxWorkspaceEvent) {
|
||||
if ((tx as TxWorkspaceEvent).event === WorkspaceEvent.Upgrade) {
|
||||
onUpgrade?.()
|
||||
}
|
||||
}
|
||||
handler(tx)
|
||||
}
|
||||
|
||||
return connect(url.href, upgradeHandler, onUpgrade, onUnauthorized, onConnect)
|
||||
},
|
||||
filterModel ? getPlugins() : undefined
|
||||
)
|
||||
|
@ -57,7 +57,7 @@ export type ClientFactory = (
|
||||
endpoint: string,
|
||||
onUpgrade?: () => void,
|
||||
onUnauthorized?: () => void,
|
||||
onConnect?: () => void
|
||||
onConnect?: (apply: boolean) => void
|
||||
) => Promise<Client>
|
||||
|
||||
export default plugin(clientId, {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import client from '@hcengineering/client'
|
||||
import contact from '@hcengineering/contact'
|
||||
import core, { Client, setCurrentAccount, Version } from '@hcengineering/core'
|
||||
import core, { Client, setCurrentAccount, Version, versionToString } from '@hcengineering/core'
|
||||
import login, { loginId } from '@hcengineering/login'
|
||||
import { getMetadata, getResource, setMetadata } from '@hcengineering/platform'
|
||||
import presentation, { refreshClient, setClient } from '@hcengineering/presentation'
|
||||
@ -41,6 +41,8 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
let clientSet = false
|
||||
|
||||
let version: Version | undefined
|
||||
|
||||
const clientFactory = await getResource(client.function.GetClient)
|
||||
_client = await clientFactory(
|
||||
token,
|
||||
@ -56,11 +58,24 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
})
|
||||
},
|
||||
// We need to refresh all active live queries and clear old queries.
|
||||
() => {
|
||||
(apply: boolean) => {
|
||||
try {
|
||||
if (clientSet) {
|
||||
if (clientSet && !apply) {
|
||||
void refreshClient()
|
||||
}
|
||||
|
||||
void (async () => {
|
||||
const newVersion = await _client?.findOne<Version>(core.class.Version, {})
|
||||
console.log('Reconnect Model version', version)
|
||||
|
||||
const currentVersionStr = versionToString(version as Version)
|
||||
const reconnectVersionStr = versionToString(newVersion as Version)
|
||||
|
||||
if (currentVersionStr !== reconnectVersionStr) {
|
||||
// It seems upgrade happened
|
||||
location.reload()
|
||||
}
|
||||
})()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
@ -87,13 +102,13 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
}
|
||||
|
||||
try {
|
||||
const version = await _client.findOne<Version>(core.class.Version, {})
|
||||
version = await _client.findOne<Version>(core.class.Version, {})
|
||||
console.log('Model version', version)
|
||||
|
||||
const requirdVersion = getMetadata(presentation.metadata.RequiredVersion)
|
||||
if (requirdVersion !== undefined) {
|
||||
if (requirdVersion !== undefined && version !== undefined) {
|
||||
console.log('checking min model version', requirdVersion)
|
||||
const versionStr = `${version?.major as number}.${version?.minor as number}.${version?.patch as number}`
|
||||
const versionStr = versionToString(version)
|
||||
|
||||
if (version === undefined || requirdVersion !== versionStr) {
|
||||
versionError = `${versionStr} => ${requirdVersion}`
|
||||
|
@ -175,7 +175,7 @@ class TServerStorage implements ServerStorage {
|
||||
const txCUD = TxProcessor.extractTx(tx) as TxCUD<Doc>
|
||||
if (!this.hierarchy.isDerived(txCUD._class, core.class.TxCUD)) {
|
||||
// Skip unsupported tx
|
||||
console.error('Unsupported transacton', tx)
|
||||
console.error('Unsupported transaction', tx)
|
||||
continue
|
||||
}
|
||||
const domain = this.hierarchy.getDomain(txCUD.objectClass)
|
||||
@ -640,7 +640,7 @@ class TServerStorage implements ServerStorage {
|
||||
}
|
||||
|
||||
if (tx.objectSpace === core.space.Model) {
|
||||
// maintain hiearachy and triggers
|
||||
// maintain hierarchy and triggers
|
||||
this.hierarchy.tx(tx)
|
||||
await this.triggers.tx(tx)
|
||||
await this.modelDb.tx(tx)
|
||||
|
Loading…
Reference in New Issue
Block a user