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