UBERF-6374: Improve server logging and improve startup performance (#5210)

This commit is contained in:
Andrey Sobolev
2024-04-06 15:14:06 +07:00
committed by GitHub
parent ceac67f3a3
commit 034700a65b
39 changed files with 631 additions and 405 deletions
+1 -6
View File
@@ -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[]>
}
/**
+1 -1
View File
@@ -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()
}
+15 -14
View File
@@ -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 })
}
}
})
-11
View File
@@ -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)
}
}
}
}
/**
+6 -6
View File
@@ -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)
}
+11 -21
View File
@@ -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',
{},
+5 -9
View File
@@ -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) => {