Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UBERF-8259: Do not store system model into DB #6716

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
"MINIO_ACCESS_KEY": "minioadmin",
"MINIO_SECRET_KEY": "minioadmin",
"MINIO_ENDPOINT": "localhost",
"MODEL_VERSION": "v0.6.286"
"MODEL_VERSION": "v0.6.287"
// "INIT_SCRIPT_URL": "https://raw.githubusercontent.com/hcengineering/init/main/script.yaml",
// "INIT_WORKSPACE": "onboarding",
},
Expand Down
4 changes: 2 additions & 2 deletions dev/tool/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1503,7 +1503,7 @@ export function devTool (
.option('-w, --workspace <workspace>', 'Selected workspace only', '')
.option('-c, --concurrency <concurrency>', 'Number of documents being processed concurrently', '10')
.action(async (cmd: { workspace: string, concurrency: string }) => {
const { mongodbUri, dbUrl } = prepareTools()
const { mongodbUri, dbUrl, txes } = prepareTools()
await withDatabase(mongodbUri, async (db, client) => {
await withStorage(mongodbUri, async (adapter) => {
const workspaces = await listWorkspacesPure(db)
Expand All @@ -1521,7 +1521,7 @@ export function devTool (
workspaceUrl: workspace.workspaceUrl ?? ''
}

const { pipeline } = await getServerPipeline(toolCtx, mongodbUri, dbUrl, wsUrl)
const { pipeline } = await getServerPipeline(toolCtx, txes, mongodbUri, dbUrl, wsUrl)

await migrateMarkup(toolCtx, adapter, wsId, client, pipeline, parseInt(cmd.concurrency))

Expand Down
4 changes: 2 additions & 2 deletions dev/tool/src/markup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import core, {
} from '@hcengineering/core'
import { getMongoClient, getWorkspaceDB } from '@hcengineering/mongo'
import { type Pipeline, type StorageAdapter } from '@hcengineering/server-core'
import { connect, fetchModel } from '@hcengineering/server-tool'
import { connect } from '@hcengineering/server-tool'
import { jsonToText, markupToYDoc } from '@hcengineering/text'
import { type Db, type FindCursor, type MongoClient } from 'mongodb'

Expand Down Expand Up @@ -123,7 +123,7 @@ export async function migrateMarkup (
pipeline: Pipeline,
concurrency: number
): Promise<void> {
const { hierarchy } = await fetchModel(ctx, pipeline)
const hierarchy = pipeline.context.hierarchy

const workspaceDb = client.db(workspaceId.name)

Expand Down
3 changes: 2 additions & 1 deletion pods/backup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"dotenv": "~16.0.0",
"@hcengineering/backup-service": "^0.6.0",
"@hcengineering/analytics": "^0.6.0",
"@hcengineering/analytics-service": "^0.6.0"
"@hcengineering/analytics-service": "^0.6.0",
"@hcengineering/model-all": "^0.6.0"
}
}
11 changes: 9 additions & 2 deletions pods/backup/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
import { Analytics } from '@hcengineering/analytics'
import { configureAnalytics, SplitLogger } from '@hcengineering/analytics-service'
import { startBackup } from '@hcengineering/backup-service'
import { MeasureMetricsContext, metricsToString, newMetrics } from '@hcengineering/core'
import { MeasureMetricsContext, metricsToString, newMetrics, type Tx } from '@hcengineering/core'
import { type PipelineFactory } from '@hcengineering/server-core'
import { createBackupPipeline, getConfig } from '@hcengineering/server-pipeline'
import { writeFile } from 'fs/promises'
import { join } from 'path'

import builder from '@hcengineering/model-all'

const enabled = (process.env.MODEL_ENABLED ?? '*').split(',').map((it) => it.trim())
const disabled = (process.env.MODEL_DISABLED ?? '').split(',').map((it) => it.trim())

const model = JSON.parse(JSON.stringify(builder(enabled, disabled).getTxes())) as Tx[]

const metricsContext = new MeasureMetricsContext(
'backup',
{},
Expand Down Expand Up @@ -58,7 +65,7 @@ const onClose = (): void => {
startBackup(
metricsContext,
(mongoUrl, storageAdapter) => {
const factory: PipelineFactory = createBackupPipeline(metricsContext, mongoUrl, {
const factory: PipelineFactory = createBackupPipeline(metricsContext, mongoUrl, model, {
externalStorage: storageAdapter,
usePassedCtx: true
})
Expand Down
3 changes: 2 additions & 1 deletion pods/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@hcengineering/server-telegram": "^0.6.0",
"@hcengineering/pod-telegram-bot": "^0.6.0",
"@hcengineering/server-ai-bot": "^0.6.0",
"@hcengineering/server-ai-bot-resources": "^0.6.0"
"@hcengineering/server-ai-bot-resources": "^0.6.0",
"@hcengineering/model-all": "^0.6.0"
}
}
10 changes: 9 additions & 1 deletion pods/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// limitations under the License.
//

import { type Branding, type BrandingMap, type WorkspaceIdWithUrl } from '@hcengineering/core'
import { type Branding, type BrandingMap, type Tx, type WorkspaceIdWithUrl } from '@hcengineering/core'
import { buildStorageFromConfig, getMetricsContext } from '@hcengineering/server'

import { ClientSession, startSessionManager, type ServerFactory, type Session } from '@hcengineering/server'
Expand All @@ -25,6 +25,13 @@ import { serverAiBotId } from '@hcengineering/server-ai-bot'
import { createAIBotAdapter } from '@hcengineering/server-ai-bot-resources'
import { createServerPipeline, registerServerPlugins, registerStringLoaders } from '@hcengineering/server-pipeline'

import builder from '@hcengineering/model-all'

const enabled = (process.env.MODEL_ENABLED ?? '*').split(',').map((it) => it.trim())
const disabled = (process.env.MODEL_DISABLED ?? '').split(',').map((it) => it.trim())

const model = JSON.parse(JSON.stringify(builder(enabled, disabled).getTxes())) as Tx[]

registerStringLoaders()

/**
Expand Down Expand Up @@ -64,6 +71,7 @@ export function start (
const pipelineFactory = createServerPipeline(
metrics,
dbUrls,
model,
{ ...opt, externalStorage, adapterSecurity: rawDbUrl !== undefined },
{
serviceAdapters: {
Expand Down
44 changes: 39 additions & 5 deletions server/middleware/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,22 @@
//

import core, {
type Doc,
type LoadModelResponse,
type MeasureContext,
type Timestamp,
type Tx,
type TxCUD,
DOMAIN_TX
} from '@hcengineering/core'
import { PlatformError, unknownError } from '@hcengineering/platform'
import type { Middleware, PipelineContext, TxAdapter, TxMiddlewareResult } from '@hcengineering/server-core'
import type {
Middleware,
MiddlewareCreator,
PipelineContext,
TxAdapter,
TxMiddlewareResult
} from '@hcengineering/server-core'
import { BaseMiddleware } from '@hcengineering/server-core'
import crypto from 'node:crypto'

Expand All @@ -34,28 +42,54 @@ export class ModelMiddleware extends BaseMiddleware implements Middleware {
lastHashResponse!: Promise<LoadModelResponse>
model!: Tx[]

static async create (ctx: MeasureContext, context: PipelineContext, next?: Middleware): Promise<Middleware> {
const middleware = new ModelMiddleware(context, next)
constructor (
context: PipelineContext,
next: Middleware | undefined,
readonly systemTx: Tx[]
) {
super(context, next)
}

static async doCreate (
ctx: MeasureContext,
context: PipelineContext,
next: Middleware | undefined,
systemTx: Tx[]
): Promise<Middleware> {
const middleware = new ModelMiddleware(context, next, systemTx)
await middleware.init(ctx)
return middleware
}

static create (tx: Tx[]): MiddlewareCreator {
return (ctx, context, next) => {
return this.doCreate(ctx, context, next, tx)
}
}

async init (ctx: MeasureContext): Promise<void> {
if (this.context.adapterManager == null) {
throw new PlatformError(unknownError('Adapter manager should be configured'))
}
const txAdapter = this.context.adapterManager.getAdapter(DOMAIN_TX, true) as TxAdapter

const isUserTx = (it: Tx): boolean =>
it.modifiedBy !== core.account.System ||
(it as TxCUD<Doc>).objectClass === 'contact:class:Person' ||
(it as TxCUD<Doc>).objectClass === 'contact:class:PersonAccount'

this.model = await ctx.with('get-model', {}, async (ctx) => {
const model = await ctx.with('fetch-model', {}, (ctx) => txAdapter.getModel(ctx))
const allUserTxes = await ctx.with('fetch-model', {}, (ctx) => txAdapter.getModel(ctx))
const userTxes = allUserTxes.filter((it) => isUserTx(it))
const model = this.systemTx.concat(userTxes)
for (const tx of model) {
try {
this.context.hierarchy.tx(tx)
} catch (err: any) {
ctx.warn('failed to apply model transaction, skipping', { tx: JSON.stringify(tx), err })
}
}
this.context.modelDb.addTxes(ctx, model, false)
this.context.modelDb.addTxes(ctx, model, true)
return model
})

Expand Down
6 changes: 4 additions & 2 deletions server/mongo/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,9 @@ abstract class MongoAdapterBase implements DbAdapter {

async clean (ctx: MeasureContext, domain: Domain, docs: Ref<Doc>[]): Promise<void> {
await ctx.with('clean', {}, async () => {
await this.db.collection<Doc>(domain).deleteMany({ _id: { $in: docs } })
if (docs.length > 0) {
await this.db.collection<Doc>(domain).deleteMany({ _id: { $in: docs } })
}
})
}
}
Expand Down Expand Up @@ -1693,7 +1695,7 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
)
}
model.forEach((tx) => (tx.modifiedBy === core.account.System && !isPersonAccount(tx) ? systemTx : userTx).push(tx))
return systemTx.concat(userTx)
return this.stripHash(systemTx.concat(userTx)) as Tx[]
}
}

Expand Down
1 change: 1 addition & 0 deletions server/mongo/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export class DBCollectionHelper implements DomainHelperOperations {
}

async init (domain?: Domain): Promise<void> {
// Check and create DB if missin
if (domain === undefined) {
// Init existing collecfions
for (const c of (await this.db.listCollections({}, { nameOnly: true }).toArray()).map((it) => it.name)) {
Expand Down
9 changes: 7 additions & 2 deletions server/server-pipeline/src/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ModelDb,
type Branding,
type MeasureContext,
type Tx,
type WorkspaceIdWithUrl
} from '@hcengineering/core'
import { createElasticAdapter, createElasticBackupDataAdapter } from '@hcengineering/elastic'
Expand Down Expand Up @@ -99,6 +100,7 @@ export function getTxAdapterFactory (
export function createServerPipeline (
metrics: MeasureContext,
dbUrls: string,
model: Tx[],
opt: {
fullTextUrl: string
rekoniUrl: string
Expand Down Expand Up @@ -137,7 +139,7 @@ export function createServerPipeline (
DomainFindMiddleware.create,
DomainTxMiddleware.create,
DBAdapterInitMiddleware.create,
ModelMiddleware.create,
ModelMiddleware.create(model),
DBAdapterMiddleware.create(conf), // Configure DB adapters
BroadcastMiddleware.create(broadcast)
]
Expand All @@ -162,6 +164,7 @@ export function createServerPipeline (
export function createBackupPipeline (
metrics: MeasureContext,
dbUrls: string,
systemTx: Tx[],
opt: {
usePassedCtx?: boolean
adapterSecurity?: boolean
Expand Down Expand Up @@ -206,7 +209,7 @@ export function createBackupPipeline (
ContextNameMiddleware.create,
DomainFindMiddleware.create,
DBAdapterInitMiddleware.create,
ModelMiddleware.create,
ModelMiddleware.create(systemTx),
DBAdapterMiddleware.create(conf)
]

Expand All @@ -225,6 +228,7 @@ export function createBackupPipeline (

export async function getServerPipeline (
ctx: MeasureContext,
model: Tx[],
mongodbUri: string,
dbUrl: string | undefined,
wsUrl: WorkspaceIdWithUrl
Expand All @@ -240,6 +244,7 @@ export async function getServerPipeline (
const pipelineFactory = createServerPipeline(
ctx,
dbUrls,
model,
{
externalStorage: storageAdapter,
fullTextUrl: 'http://localhost:9200',
Expand Down
Loading