mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-11 12:17:44 +02:00
UBERF-6374: Improve server logging and improve startup performance (#5210)
This commit is contained in:
@@ -50,11 +50,6 @@ export interface RawDBAdapter {
|
||||
* @public
|
||||
*/
|
||||
export interface DbAdapter {
|
||||
/**
|
||||
* Method called after hierarchy is ready to use.
|
||||
*/
|
||||
init: (model: Tx[]) => Promise<void>
|
||||
|
||||
createIndexes: (domain: Domain, config: Pick<IndexingConfiguration<Doc>, 'indexes'>) => Promise<void>
|
||||
removeOldIndex: (domain: Domain, deletePattern: RegExp, keepPattern: RegExp) => Promise<void>
|
||||
|
||||
@@ -83,7 +78,7 @@ export interface DbAdapter {
|
||||
* @public
|
||||
*/
|
||||
export interface TxAdapter extends DbAdapter {
|
||||
getModel: () => Promise<Tx[]>
|
||||
getModel: (ctx: MeasureContext) => Promise<Tx[]>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,7 +63,7 @@ export class FullTextIndex implements WithFind {
|
||||
readonly indexer: FullTextIndexPipeline,
|
||||
private readonly upgrade: boolean
|
||||
) {
|
||||
if (!upgrade) {
|
||||
if (!this.upgrade) {
|
||||
// Schedule indexing after consistency check
|
||||
void this.indexer.startIndexing()
|
||||
}
|
||||
|
||||
@@ -91,13 +91,12 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
}
|
||||
|
||||
async cancel (): Promise<void> {
|
||||
console.log(this.workspace.name, 'Cancel indexing', this.indexId)
|
||||
this.cancelling = true
|
||||
clearTimeout(this.skippedReiterationTimeout)
|
||||
this.triggerIndexing()
|
||||
await this.indexing
|
||||
await this.flush(true)
|
||||
console.log(this.workspace.name, 'Indexing canceled', this.indexId)
|
||||
await this.metrics.info('Cancel indexing', { workspace: this.workspace.name, indexId: this.indexId })
|
||||
}
|
||||
|
||||
async markRemove (doc: DocIndexState): Promise<void> {
|
||||
@@ -336,7 +335,10 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
try {
|
||||
this.hierarchy.getClass(core.class.DocIndexState)
|
||||
} catch (err: any) {
|
||||
console.log(this.workspace.name, 'Models is not upgraded to support indexer', this.indexId)
|
||||
await this.metrics.info('Models is not upgraded to support indexer', {
|
||||
indexId: this.indexId,
|
||||
workspace: this.workspace.name
|
||||
})
|
||||
return
|
||||
}
|
||||
await this.metrics.with('init-states', {}, async () => {
|
||||
@@ -367,12 +369,12 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
_classes.forEach((it) => this.broadcastClasses.add(it))
|
||||
|
||||
if (this.triggerCounts > 0) {
|
||||
console.log('No wait, trigger counts', this.triggerCounts)
|
||||
await this.metrics.info('No wait, trigger counts', { triggerCount: this.triggerCounts })
|
||||
}
|
||||
|
||||
if (this.toIndex.size === 0 && this.stageChanged === 0 && this.triggerCounts === 0) {
|
||||
if (this.toIndex.size === 0) {
|
||||
console.log(this.workspace.name, 'Indexing complete', this.indexId)
|
||||
await this.metrics.info('Indexing complete', { indexId: this.indexId, workspace: this.workspace.name })
|
||||
}
|
||||
if (!this.cancelling) {
|
||||
// We need to send index update event
|
||||
@@ -398,7 +400,7 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(this.workspace.name, 'Exit indexer', this.indexId)
|
||||
await this.metrics.info('Exit indexer', { indexId: this.indexId, workspace: this.workspace.name })
|
||||
}
|
||||
|
||||
private async processIndex (ctx: MeasureContext): Promise<Ref<Class<Doc>>[]> {
|
||||
@@ -470,13 +472,12 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
}
|
||||
|
||||
if (result.length > 0) {
|
||||
console.log(
|
||||
this.workspace.name,
|
||||
`Full text: Indexing ${this.indexId} ${st.stageId}`,
|
||||
Object.entries(this.currentStages)
|
||||
.map((it) => `${it[0]}:${it[1]}`)
|
||||
.join(' ')
|
||||
)
|
||||
await this.metrics.info('Full text: Indexing', {
|
||||
indexId: this.indexId,
|
||||
stageId: st.stageId,
|
||||
workspace: this.workspace.name,
|
||||
...this.currentStages
|
||||
})
|
||||
} else {
|
||||
// Nothing to index, check on next cycle.
|
||||
break
|
||||
@@ -528,7 +529,7 @@ export class FullTextIndexPipeline implements FullTextPipeline {
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
await this.metrics.error('error during index', { error: err })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -38,7 +38,6 @@ import { type DbAdapter } from './adapter'
|
||||
* @public
|
||||
*/
|
||||
export class DummyDbAdapter implements DbAdapter {
|
||||
async init (model: Tx[]): Promise<void> {}
|
||||
async findAll<T extends Doc>(
|
||||
ctx: MeasureContext,
|
||||
_class: Ref<Class<T>>,
|
||||
@@ -99,16 +98,6 @@ class InMemoryAdapter extends DummyDbAdapter implements DbAdapter {
|
||||
async tx (ctx: MeasureContext, ...tx: Tx[]): Promise<TxResult[]> {
|
||||
return await this.modeldb.tx(...tx)
|
||||
}
|
||||
|
||||
async init (model: Tx[]): Promise<void> {
|
||||
for (const tx of model) {
|
||||
try {
|
||||
await this.modeldb.tx(tx)
|
||||
} catch (err: any) {
|
||||
console.error('skip broken TX', err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,8 +31,8 @@ import {
|
||||
type Tx,
|
||||
type TxResult
|
||||
} from '@hcengineering/core'
|
||||
import { createServerStorage } from './server'
|
||||
import { type DbConfiguration } from './configuration'
|
||||
import { createServerStorage } from './server'
|
||||
import {
|
||||
type BroadcastFunc,
|
||||
type HandledBroadcastFunc,
|
||||
@@ -67,12 +67,12 @@ export async function createPipeline (
|
||||
}
|
||||
})
|
||||
)
|
||||
const pipeline = ctx.with(
|
||||
'create pipeline',
|
||||
{},
|
||||
async (ctx) => await PipelineImpl.create(ctx, storage, constructors, broadcast)
|
||||
const pipelineResult = await PipelineImpl.create(
|
||||
ctx.newChild('pipeline-operations', {}),
|
||||
storage,
|
||||
constructors,
|
||||
broadcast
|
||||
)
|
||||
const pipelineResult = await pipeline
|
||||
broadcastHook = (tx, targets) => {
|
||||
return pipelineResult.handleBroadcast(tx, targets)
|
||||
}
|
||||
|
||||
@@ -56,18 +56,20 @@ export async function createServerStorage (
|
||||
|
||||
const storageAdapter = conf.storageFactory?.()
|
||||
|
||||
for (const key in conf.adapters) {
|
||||
const adapterConf = conf.adapters[key]
|
||||
adapters.set(
|
||||
key,
|
||||
await adapterConf.factory(ctx, hierarchy, adapterConf.url, conf.workspace, modelDb, storageAdapter)
|
||||
)
|
||||
}
|
||||
await ctx.with('create-adapters', {}, async (ctx) => {
|
||||
for (const key in conf.adapters) {
|
||||
const adapterConf = conf.adapters[key]
|
||||
adapters.set(
|
||||
key,
|
||||
await adapterConf.factory(ctx, hierarchy, adapterConf.url, conf.workspace, modelDb, storageAdapter)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const txAdapter = adapters.get(conf.domains[DOMAIN_TX]) as TxAdapter
|
||||
|
||||
const model = await ctx.with('get model', {}, async (ctx) => {
|
||||
const model = await txAdapter.getModel()
|
||||
const model = await ctx.with('fetch-model', {}, async (ctx) => await txAdapter.getModel(ctx))
|
||||
for (const tx of model) {
|
||||
try {
|
||||
hierarchy.tx(tx)
|
||||
@@ -76,22 +78,10 @@ export async function createServerStorage (
|
||||
console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err)
|
||||
}
|
||||
}
|
||||
for (const tx of model) {
|
||||
try {
|
||||
await modelDb.tx(tx)
|
||||
} catch (err: any) {
|
||||
console.error('failed to apply model transaction, skipping', JSON.stringify(tx), err)
|
||||
}
|
||||
}
|
||||
modelDb.addTxes(ctx, model, false)
|
||||
return model
|
||||
})
|
||||
|
||||
for (const [adn, adapter] of adapters) {
|
||||
await ctx.with('init-adapter', { name: adn }, async (ctx) => {
|
||||
await adapter.init(model)
|
||||
})
|
||||
}
|
||||
|
||||
const fulltextAdapter = await ctx.with(
|
||||
'create full text adapter',
|
||||
{},
|
||||
|
||||
@@ -60,10 +60,10 @@ import crypto from 'node:crypto'
|
||||
import { type DbAdapter } from '../adapter'
|
||||
import { type FullTextIndex } from '../fulltext'
|
||||
import serverCore from '../plugin'
|
||||
import { type ServiceAdaptersManager } from '../service'
|
||||
import { type StorageAdapter } from '../storage'
|
||||
import { type Triggers } from '../triggers'
|
||||
import type { FullTextAdapter, ObjectDDParticipant, ServerStorageOptions, TriggerControl } from '../types'
|
||||
import { type StorageAdapter } from '../storage'
|
||||
import { type ServiceAdaptersManager } from '../service'
|
||||
|
||||
export class TServerStorage implements ServerStorage {
|
||||
private readonly fulltext: FullTextIndex
|
||||
@@ -137,15 +137,11 @@ export class TServerStorage implements ServerStorage {
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
console.timeLog(this.workspace.name, 'closing')
|
||||
await this.fulltext.close()
|
||||
console.timeLog(this.workspace.name, 'closing adapters')
|
||||
for (const o of this.adapters.values()) {
|
||||
await o.close()
|
||||
}
|
||||
console.timeLog(this.workspace.name, 'closing fulltext')
|
||||
await this.fulltextAdapter.close()
|
||||
console.timeLog(this.workspace.name, 'closing service adapters')
|
||||
await this.serviceAdaptersManager.close()
|
||||
}
|
||||
|
||||
@@ -199,7 +195,7 @@ export 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 transaction', tx)
|
||||
await ctx.error('Unsupported transaction', tx)
|
||||
continue
|
||||
}
|
||||
const domain = this.hierarchy.getDomain(txCUD.objectClass)
|
||||
@@ -397,7 +393,7 @@ export class TServerStorage implements ServerStorage {
|
||||
{ clazz, query, options }
|
||||
)
|
||||
if (Date.now() - st > 1000) {
|
||||
console.error('FindAll', Date.now() - st, clazz, query, options)
|
||||
await ctx.error('FindAll', { time: Date.now() - st, clazz, query, options })
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -794,7 +790,7 @@ export class TServerStorage implements ServerStorage {
|
||||
await fx()
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.log(err)
|
||||
await ctx.error('error process tx', { error: err })
|
||||
throw err
|
||||
} finally {
|
||||
onEnds.forEach((p) => {
|
||||
|
||||
Reference in New Issue
Block a user