mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 00:37:47 +00:00
Optimize model (#3795)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
65e0e33279
commit
c15f253c15
@ -16,6 +16,7 @@
|
|||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
import chunter, { Comment } from '@hcengineering/chunter'
|
import chunter, { Comment } from '@hcengineering/chunter'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
|
import { deepEqual } from 'fast-equals'
|
||||||
import core, {
|
import core, {
|
||||||
BackupClient,
|
BackupClient,
|
||||||
Client as CoreClient,
|
Client as CoreClient,
|
||||||
@ -23,6 +24,7 @@ import core, {
|
|||||||
Doc,
|
Doc,
|
||||||
Domain,
|
Domain,
|
||||||
Ref,
|
Ref,
|
||||||
|
SortingOrder,
|
||||||
TxCreateDoc,
|
TxCreateDoc,
|
||||||
TxOperations,
|
TxOperations,
|
||||||
TxProcessor,
|
TxProcessor,
|
||||||
@ -177,6 +179,78 @@ export async function cleanRemovedTransactions (workspaceId: WorkspaceId, transa
|
|||||||
await connection.close()
|
await connection.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function optimizeModel (workspaceId: WorkspaceId, transactorUrl: string): Promise<void> {
|
||||||
|
const connection = (await connect(transactorUrl, workspaceId, undefined, {
|
||||||
|
mode: 'backup',
|
||||||
|
model: 'upgrade'
|
||||||
|
})) as unknown as CoreClient & BackupClient
|
||||||
|
try {
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
const model = connection.getModel()
|
||||||
|
|
||||||
|
const updateTransactions = await connection.findAll(
|
||||||
|
core.class.TxUpdateDoc,
|
||||||
|
{
|
||||||
|
objectSpace: core.space.Model,
|
||||||
|
_class: core.class.TxUpdateDoc
|
||||||
|
},
|
||||||
|
{ sort: { _id: SortingOrder.Ascending, modifiedOn: SortingOrder.Ascending }, limit: 5000 }
|
||||||
|
)
|
||||||
|
|
||||||
|
const toRemove: Ref<Doc>[] = []
|
||||||
|
|
||||||
|
let i = 0
|
||||||
|
for (const tx of updateTransactions) {
|
||||||
|
try {
|
||||||
|
const doc = model.findObject(tx.objectId)
|
||||||
|
if (doc === undefined) {
|
||||||
|
// Document is removed, we could remove update transaction at all
|
||||||
|
toRemove.push(tx._id)
|
||||||
|
console.log('marking update tx to remove', tx)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const opt: any = { ...tx.operations }
|
||||||
|
const adoc = doc as any
|
||||||
|
|
||||||
|
let uDoc: any = {}
|
||||||
|
|
||||||
|
// Find next update operations for same doc
|
||||||
|
for (const ops of updateTransactions.slice(i + 1).filter((it) => it.objectId === tx.objectId)) {
|
||||||
|
uDoc = { ...uDoc, ...ops.operations }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [k, v] of Object.entries(opt)) {
|
||||||
|
// If value is same as in document or we have more transactions with same value updated.
|
||||||
|
if (!k.startsWith('$') && (!deepEqual(adoc[k], v) || uDoc[k] !== undefined)) {
|
||||||
|
// Current value is not we modify
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
|
delete opt[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(opt).length === 0) {
|
||||||
|
// No operations pending, remove update tx.
|
||||||
|
toRemove.push(tx._id)
|
||||||
|
console.log('marking update tx to remove, since not real update is performed', tx)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await connection.clean(DOMAIN_TX, toRemove)
|
||||||
|
|
||||||
|
count += toRemove.length
|
||||||
|
console.log('processed', count)
|
||||||
|
|
||||||
|
console.log('total docs with remove', count)
|
||||||
|
} catch (err: any) {
|
||||||
|
console.trace(err)
|
||||||
|
} finally {
|
||||||
|
await connection.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
export async function cleanArchivedSpaces (workspaceId: WorkspaceId, transactorUrl: string): Promise<void> {
|
export async function cleanArchivedSpaces (workspaceId: WorkspaceId, transactorUrl: string): Promise<void> {
|
||||||
const connection = (await connect(transactorUrl, workspaceId, undefined, {
|
const connection = (await connect(transactorUrl, workspaceId, undefined, {
|
||||||
mode: 'backup'
|
mode: 'backup'
|
||||||
|
@ -52,7 +52,13 @@ import { MinioService } from '@hcengineering/minio'
|
|||||||
import { MigrateOperation } from '@hcengineering/model'
|
import { MigrateOperation } from '@hcengineering/model'
|
||||||
import { openAIConfigDefaults } from '@hcengineering/openai'
|
import { openAIConfigDefaults } from '@hcengineering/openai'
|
||||||
import { benchmark } from './benchmark'
|
import { benchmark } from './benchmark'
|
||||||
import { cleanArchivedSpaces, cleanRemovedTransactions, cleanWorkspace, fixCommentDoubleIdCreate } from './clean'
|
import {
|
||||||
|
cleanArchivedSpaces,
|
||||||
|
cleanRemovedTransactions,
|
||||||
|
cleanWorkspace,
|
||||||
|
fixCommentDoubleIdCreate,
|
||||||
|
optimizeModel
|
||||||
|
} from './clean'
|
||||||
import { changeConfiguration } from './configuration'
|
import { changeConfiguration } from './configuration'
|
||||||
import { fixMixinForeignAttributes, showMixinForeignAttributes } from './mixin'
|
import { fixMixinForeignAttributes, showMixinForeignAttributes } from './mixin'
|
||||||
import { openAIConfig } from './openai'
|
import { openAIConfig } from './openai'
|
||||||
@ -499,6 +505,14 @@ export function devTool (
|
|||||||
await changeConfiguration(getWorkspaceId(workspace, productId), transactorUrl, cmd)
|
await changeConfiguration(getWorkspaceId(workspace, productId), transactorUrl, cmd)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('optimize-model <workspace>')
|
||||||
|
.description('optimize model')
|
||||||
|
.action(async (workspace: string, cmd: { enable: string, disable: string, list: boolean }) => {
|
||||||
|
console.log(JSON.stringify(cmd))
|
||||||
|
await optimizeModel(getWorkspaceId(workspace, productId), transactorUrl)
|
||||||
|
})
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('benchmark')
|
.command('benchmark')
|
||||||
.description('clean archived spaces')
|
.description('clean archived spaces')
|
||||||
|
@ -77,6 +77,11 @@ export abstract class MemDb extends TxProcessor implements Storage {
|
|||||||
return doc as T
|
return doc as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findObject<T extends Doc>(_id: Ref<T>): T | undefined {
|
||||||
|
const doc = this.objectById.get(_id)
|
||||||
|
return doc as T
|
||||||
|
}
|
||||||
|
|
||||||
private async getLookupValue<T extends Doc>(
|
private async getLookupValue<T extends Doc>(
|
||||||
_class: Ref<Class<T>>,
|
_class: Ref<Class<T>>,
|
||||||
doc: T,
|
doc: T,
|
||||||
|
Loading…
Reference in New Issue
Block a user