UBERF-9501: Fix use of Date.now() (#8069)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / uitest-workspaces (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions

This commit is contained in:
Andrey Sobolev 2025-02-21 19:46:13 +07:00 committed by GitHub
parent 4429d33c68
commit 3673078b11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 150 additions and 126 deletions

View File

@ -31,7 +31,9 @@ import core, {
type Ref,
type WorkspaceUuid,
SocialIdType,
type PersonUuid
type PersonUuid,
platformNow,
platformNowDiff
} from '@hcengineering/core'
import { generateToken } from '@hcengineering/server-token'
import { connect } from '@hcengineering/server-tool'
@ -214,7 +216,7 @@ export async function benchmark (
let timer: any
if (isMainThread && monitorConnection !== undefined) {
timer = setInterval(() => {
const st = Date.now()
const st = platformNow()
try {
const fetchUrl = endpoint.replace('ws:/', 'http:/') + '/api/v1/statistics?token=' + token
@ -269,7 +271,7 @@ export async function benchmark (
}
})
.then((res) => {
const cur = Date.now() - st
const cur = platformNow() - st
opTime += cur
moment = cur
ops++
@ -518,7 +520,7 @@ export async function testFindAll (endpoint: string, workspace: WorkspaceUuid, a
const connection = await connect(endpoint, workspace, account)
try {
const client = new TxOperations(connection, core.account.System)
const start = Date.now()
const start = platformNow()
const res = await client.findAll(
recruit.class.Applicant,
{},
@ -529,7 +531,7 @@ export async function testFindAll (endpoint: string, workspace: WorkspaceUuid, a
}
}
)
console.log('Find all', res.length, 'time', Date.now() - start)
console.log('Find all', res.length, 'time', platformNow() - start)
} finally {
await connection.close()
}
@ -550,7 +552,7 @@ export async function generateWorkspaceData (
throw new Error('User not found')
}
const employees: PersonId[] = [emailSocialString]
const start = Date.now()
const start = platformNow()
for (let i = 0; i < 100; i++) {
const socialString = await generateEmployee(client)
employees.push(socialString)
@ -566,7 +568,7 @@ export async function generateWorkspaceData (
await generateVacancy(client, employees)
}
}
console.log('Generate', Date.now() - start)
console.log('Generate', platformNowDiff(start))
} finally {
await connection.close()
}

View File

@ -58,7 +58,9 @@ import core, {
generateId,
getObjectValue,
toIdMap,
updateAttribute
updateAttribute,
platformNow,
platformNowDiff
} from '@hcengineering/core'
import activity, { DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
import { DOMAIN_SPACE } from '@hcengineering/model-core'
@ -104,11 +106,10 @@ export async function cleanWorkspace (
for (const c of part) {
await op.remove(c)
}
const t = Date.now()
const t = platformNow()
console.log('remove:', part.map((it) => it.name).join(', '))
await op.commit()
const t2 = Date.now()
console.log('remove time:', t2 - t, filter.length)
console.log('remove time:', platformNowDiff(t), filter.length)
}
}
@ -122,10 +123,9 @@ export async function cleanWorkspace (
for (const c of part) {
await op.remove(c)
}
const t = Date.now()
const t = platformNow()
await op.commit()
const t2 = Date.now()
console.log('remove time:', t2 - t, issues.length)
console.log('remove time:', platformNowDiff(t), issues.length)
}
}

View File

@ -23,7 +23,7 @@ import { ModelDb } from './memdb'
import type { DocumentQuery, FindOptions, FindResult, FulltextStorage, Storage, TxResult, WithLookup } from './storage'
import { SearchOptions, SearchQuery, SearchResult } from './storage'
import { Tx, TxCUD, WorkspaceEvent, type TxWorkspaceEvent } from './tx'
import { toFindResult } from './utils'
import { platformNow, platformNowDiff, toFindResult } from './utils'
/**
* @public
@ -345,7 +345,7 @@ async function loadModel (
conn: ClientConnection,
persistence?: TxPersistenceStore
): Promise<{ mode: 'same' | 'addition' | 'upgrade', current: Tx[], addition: Tx[] }> {
const t = Date.now()
const t = platformNow()
const current = (await ctx.with('persistence-load', {}, () => persistence?.load())) ?? {
full: true,
@ -385,7 +385,7 @@ async function loadModel (
})
if (typeof window !== 'undefined') {
console.log('find' + (result.full ? 'full model' : 'model diff'), result.transactions.length, Date.now() - t)
console.log('find' + (result.full ? 'full model' : 'model diff'), result.transactions.length, platformNowDiff(t))
}
if (result.full) {
return { mode: 'upgrade', current: result.transactions, addition: [] }

View File

@ -1,6 +1,6 @@
// Basic performance metrics suite.
import { generateId } from '../utils'
import { generateId, platformNow, platformNowDiff } from '../utils'
import { childMetrics, newMetrics, updateMeasure } from './metrics'
import {
FullParamsType,
@ -61,7 +61,7 @@ export class MeasureMetricsContext implements MeasureContext {
metrics: Metrics
id?: string
st = Date.now()
st = platformNow()
contextData: object = {}
private done (value?: number, override?: boolean): void {
updateMeasure(this.metrics, this.st, this.params, this.fullParams, (spend) => {}, value, override)
@ -166,10 +166,10 @@ export class MeasureMetricsContext implements MeasureContext {
op: (ctx: MeasureContext) => T | Promise<T>,
fullParams?: ParamsType
): Promise<T> {
const st = Date.now()
const st = platformNow()
const r = this.with(name, params, op, fullParams)
void r.finally(() => {
this.logger.logOperation(name, Date.now() - st, { ...params, ...fullParams })
this.logger.logOperation(name, platformNowDiff(st), { ...params, ...fullParams })
})
return r
}
@ -284,7 +284,7 @@ export function registerOperationLog (ctx: MeasureContext): { opLogMetrics?: Met
if (!operationProfiling) {
return {}
}
const op: OperationLog = { start: Date.now(), ops: [], end: -1 }
const op: OperationLog = { start: platformNow(), ops: [], end: -1 }
let opLogMetrics: Metrics | undefined
if (ctx.id === undefined) {
@ -305,7 +305,7 @@ export function updateOperationLog (opLogMetrics: Metrics | undefined, op: Opera
return
}
if (op !== undefined) {
op.end = Date.now()
op.end = platformNow()
}
// We should keep only longest one entry
if (opLogMetrics?.opLog !== undefined) {
@ -352,7 +352,7 @@ export function addOperation<T> (
if (opLog !== undefined) {
opEntry = {
op: name,
start: Date.now(),
start: performance.now(),
params: {},
end: -1
}
@ -361,7 +361,7 @@ export function addOperation<T> (
if (opEntry !== undefined && opLog !== undefined) {
void result.finally(() => {
if (opEntry !== undefined && opLog !== undefined) {
opEntry.end = Date.now()
opEntry.end = performance.now()
opEntry.params = { ...params, ...(typeof fullParams === 'function' ? fullParams() : fullParams) }
opLog.ops.push(opEntry)
}

View File

@ -1,6 +1,7 @@
// Basic performance metrics suite.
import { MetricsData } from '.'
import { platformNow } from '../utils'
import { FullParamsType, Metrics, ParamsType } from './types'
/**
@ -65,7 +66,7 @@ export function measure (
fullParams: FullParamsType | (() => FullParamsType) = {},
endOp?: (spend: number) => void
): () => void {
const st = Date.now()
const st = platformNow()
return () => {
updateMeasure(metrics, st, params, fullParams, endOp)
}
@ -79,7 +80,7 @@ export function updateMeasure (
value?: number,
override?: boolean
): void {
const ed = Date.now()
const ed = platformNow()
const fParams = typeof fullParams === 'function' ? fullParams() : fullParams
// Update params if required
@ -136,7 +137,7 @@ export function childMetrics (root: Metrics, path: string[]): Metrics {
/**
* @public
*/
export function metricsAggregate (m: Metrics, limit: number = -1): Metrics {
export function metricsAggregate (m: Metrics, limit: number = -1, roundMath: boolean = false): Metrics {
let ms = aggregateMetrics(m.measurements, limit)
// Use child overage, if there is no top level value specified.
@ -237,7 +238,7 @@ function toString (name: string, m: Metrics, offset: number, length: number): st
* @public
*/
export function metricsToString (metrics: Metrics, name = 'System', length: number): string {
return toString(name, metricsAggregate(metrics, 50), 0, length)
return toString(name, metricsAggregate(metrics, 50, true), 0, length)
}
function printMetricsParamsRows (
@ -287,5 +288,5 @@ function toStringRows (name: string, m: Metrics, offset: number): (number | stri
* @public
*/
export function metricsToRows (metrics: Metrics, name = 'System'): (number | string)[][] {
return toStringRows(name, metricsAggregate(metrics, 50), 0)
return toStringRows(name, metricsAggregate(metrics, 50, true), 0)
}

View File

@ -1,6 +1,6 @@
import { Analytics } from '@hcengineering/analytics'
import { deepEqual } from 'fast-equals'
import { DocumentUpdate, DOMAIN_MODEL, Hierarchy, MixinData, MixinUpdate, ModelDb, toFindResult } from '.'
import { DocumentUpdate, DOMAIN_MODEL, Hierarchy, MixinData, MixinUpdate, ModelDb, platformNow, toFindResult } from '.'
import type {
PersonId,
AnyAttribute,
@ -481,10 +481,10 @@ export class ApplyOperations extends TxOperations {
this.notMatches.length === 0 &&
this.measureName == null
) {
const st = Date.now()
const st = platformNow()
// Individual update, no need for apply
await this.ops.tx(this.txes[0])
const time = Date.now() - st
const time = platformNow() - st
this.txes = []
return {
result: true,
@ -493,7 +493,7 @@ export class ApplyOperations extends TxOperations {
}
}
if (this.txes.length > 0) {
const st = Date.now()
const st = platformNow()
const aop = this.ops.txFactory.createTxApplyIf(
core.space.Tx,
this.scope,
@ -505,7 +505,7 @@ export class ApplyOperations extends TxOperations {
extraNotify
)
const result = (await this.ops.tx(aop)) as TxApplyResult
const dnow = Date.now()
const dnow = platformNow()
if (typeof window === 'object' && window !== null && this.measureName != null) {
console.log(`measure ${this.measureName}`, dnow - st, 'server time', result.serverTime)
}

View File

@ -928,3 +928,13 @@ export function pickPrimarySocialId (socialIds: SocialId[]): SocialId {
export function notEmpty<T> (id: T | undefined | null): id is T {
return id !== undefined && id !== null && id !== ''
}
/**
* Return a current performance timestamp
*/
export const platformNow: () => number = () => performance.now()
/**
* Return a diff with previous performance snapshot with 2 digits after . max.
*/
export const platformNowDiff = (old: number): number => Math.round((performance.now() - old) * 100) / 100

View File

@ -127,28 +127,28 @@ switch (args[0]) {
}
case 'transpile': {
const filesToTranspile = collectFiles(join(process.cwd(), args[1]))
let st = Date.now()
let st = performance.now()
const before = {}
const after = {}
collectFileStats('lib', before)
performESBuild(filesToTranspile)
.then(() => {
console.log("Transpile time: ", Date.now() - st)
console.log("Transpile time: ", Math.round((performance.now() - st) * 100) / 100)
collectFileStats('lib', after)
cleanNonModified(before, after)
})
break
}
case 'validate': {
let st = Date.now()
let st = performance.now()
validateTSC(st).then(() => {
console.log("Validate time: ", Date.now() - st)
console.log("Validate time: ", Math.round((performance.now() - st) * 100) / 100)
})
break
}
default: {
let st = Date.now()
let st = performance.now()
const filesToTranspile = collectFiles(join(process.cwd(), 'src'))
Promise.all(
[
@ -157,7 +157,7 @@ switch (args[0]) {
]
)
.then(() => {
console.log("Full build time: ", Date.now() - st)
console.log("Full build time: ", Math.round((performance.now() - st) * 100) / 100)
})
break
}

View File

@ -77,7 +77,7 @@ for(const a of process.argv.slice(2)) {
args.push(a)
}
}
let st = Date.now()
let st = performance.now()
execProcess(
'svelte-check',
'svelte-check', [
@ -85,6 +85,6 @@ execProcess(
...args
], useConsole)
.then(() => {
console.log("Svelte check time: ", Date.now() - st)
console.log("Svelte check time: ", Math.round((performance.now() - st) * 100) / 100)
})

View File

@ -55,6 +55,7 @@ import core, {
generateId,
getObjectValue,
matchQuery,
platformNow,
reduceCalls,
shouldShowArchived,
toFindResult
@ -187,7 +188,7 @@ export class LiveQuery implements WithTx, Client {
options?: FindOptions<T>
): Query {
const q = this.createQuery(_class, query, undefined, options)
this.queue.set(q.id, { ...q, lastUsed: Date.now() })
this.queue.set(q.id, { ...q, lastUsed: platformNow() })
if (!(q.result instanceof Promise)) {
q.result.clean()
}
@ -223,7 +224,7 @@ export class LiveQuery implements WithTx, Client {
q.result = await q.result
}
if (this.removeFromQueue(q, false)) {
this.queue.set(q.id, { ...q, lastUsed: Date.now() })
this.queue.set(q.id, { ...q, lastUsed: platformNow() })
q.result.clean()
}
return toFindResult(q.result.getClone(), q.total)
@ -265,7 +266,7 @@ export class LiveQuery implements WithTx, Client {
q.result = await q.result
}
if (this.removeFromQueue(q, false)) {
this.queue.set(q.id, { ...q, lastUsed: Date.now() })
this.queue.set(q.id, { ...q, lastUsed: platformNow() })
q.result.clean()
}
return q.result.getClone<WithLookup<T>>().shift()
@ -443,7 +444,7 @@ export class LiveQuery implements WithTx, Client {
if (!(q.result instanceof Promise)) {
q.result.clean()
}
this.queue.set(q.id, { ...q, lastUsed: Date.now() })
this.queue.set(q.id, { ...q, lastUsed: platformNow() })
}
}
}

View File

@ -35,7 +35,8 @@ import core, {
type ModelFilter,
type PluginConfiguration,
type Ref,
type TxCUD
type TxCUD,
platformNow
} from '@hcengineering/core'
import platform, { Severity, Status, getMetadata, getPlugins, setPlatformStatus } from '@hcengineering/platform'
import { connect } from './connection'
@ -46,7 +47,7 @@ let dbRequest: IDBOpenDBRequest | undefined
let dbPromise: Promise<IDBDatabase | undefined> = Promise.resolve(undefined)
if (typeof localStorage !== 'undefined') {
const st = Date.now()
const st = platformNow()
dbPromise = new Promise<IDBDatabase>((resolve) => {
dbRequest = indexedDB.open('model.db.persistence', 2)
@ -58,7 +59,7 @@ if (typeof localStorage !== 'undefined') {
}
dbRequest.onsuccess = function () {
const db = (dbRequest as IDBOpenDBRequest).result
console.log('init DB complete', Date.now() - st)
console.log('init DB complete', platformNow() - st)
resolve(db)
}
})

View File

@ -16,6 +16,8 @@
import core, {
DOMAIN_MODEL,
cutObjectArray,
platformNow,
platformNowDiff,
type Class,
type Client,
type Doc,
@ -86,7 +88,7 @@ export class PresentationClientHook implements ClientHook {
query: DocumentQuery<T>,
options?: FindOptions<T>
): Promise<WithLookup<T> | undefined> {
const startTime = Date.now()
const startTime = platformNow()
const isModel = client.getHierarchy().findDomain(_class) === DOMAIN_MODEL
const result = await client.findOne(_class, query, options)
if (this.notifyEnabled && !isModel) {
@ -100,7 +102,7 @@ export class PresentationClientHook implements ClientHook {
' =>model',
client.getModel(),
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
platformNow() - startTime,
this.stackLine()
)
}
@ -113,7 +115,7 @@ export class PresentationClientHook implements ClientHook {
query: DocumentQuery<T>,
options?: FindOptions<T>
): Promise<FindResult<T>> {
const startTime = Date.now()
const startTime = platformNow()
const isModel = client.getHierarchy().findDomain(_class) === DOMAIN_MODEL
const result = await client.findAll(_class, query, options)
if (this.notifyEnabled && !isModel) {
@ -127,7 +129,7 @@ export class PresentationClientHook implements ClientHook {
' =>model',
client.getModel(),
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
platformNow() - startTime,
JSON.stringify(result).length,
this.stackLine()
)
@ -150,7 +152,7 @@ export class PresentationClientHook implements ClientHook {
}
async tx (client: Client, tx: Tx): Promise<TxResult> {
const startTime = Date.now()
const startTime = platformNow()
const result = await client.tx(tx)
if (this.notifyEnabled && (tx as any).objectClass !== core.class.BenchmarkDoc) {
console.debug(
@ -158,7 +160,7 @@ export class PresentationClientHook implements ClientHook {
testing ? JSON.stringify(cutObjectArray(tx)).slice(0, 160) : tx,
result,
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
platformNowDiff(startTime),
this.stackLine()
)
}

View File

@ -13,7 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { Class, Doc, Ref, toIdMap } from '@hcengineering/core'
import { Class, Doc, platformNow, platformNowDiff, Ref, toIdMap } from '@hcengineering/core'
import { getEmbeddedLabel } from '@hcengineering/platform'
import { Card, getClient } from '@hcengineering/presentation'
import tags, { TagCategory, TagElement, TagReference } from '@hcengineering/tags'
@ -460,7 +460,7 @@
const client = getClient()
for (const item of searchPlanElements) {
console.log('Apply', item.original.title)
const st = Date.now()
const st = platformNow()
const ops = client.apply(undefined, 'optimize-skill')
let allRefs: TagReference[] = await client.findAll(tags.class.TagReference, { tag: item.original._id })
@ -540,7 +540,7 @@
})
}
}
console.log('Apply:commit', item.original.title, Date.now() - st)
console.log('Apply:commit', item.original.title, platformNowDiff(st))
await ops.commit(false)
processed++
}

View File

@ -158,7 +158,7 @@
attachedTo: generateId(),
attachedToClass: time.class.ToDo,
collection: 'workslots',
modifiedOn: Date.now(),
modifiedOn: now,
modifiedBy: myAccount.primarySocialId
})
slots = slots

View File

@ -1,5 +1,5 @@
<script lang="ts">
import core, { RateLimiter, concatLink, metricsAggregate, type Metrics } from '@hcengineering/core'
import core, { RateLimiter, concatLink, metricsAggregate, platformNow, type Metrics } from '@hcengineering/core'
import login from '@hcengineering/login'
import { getEmbeddedLabel, getMetadata } from '@hcengineering/platform'
import presentation, { getClient, isAdminUser, uiContext } from '@hcengineering/presentation'
@ -75,8 +75,8 @@
const rate = new RateLimiter(commandsToSendParallel)
const client = getClient()
const doOp = async () => {
const st = Date.now()
const doOp = async (): Promise<void> => {
const st = platformNow()
active++
await client.createDoc(core.class.BenchmarkDoc, core.space.Configuration, {
source: genData(dataSize),
@ -86,7 +86,7 @@
}
})
active--
const ed = Date.now()
const ed = platformNow()
if (ed - st > maxTime) {
maxTime = ed - st
@ -132,12 +132,12 @@
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
fetchStats(0)
void fetchStats(0)
}
let metrics: Metrics | undefined
function update (tick: number) {
function update (tick: number): void {
metrics = metricsAggregate(uiContext.metrics)
}
@ -183,8 +183,8 @@
</div>
<div class="flex-col p-1">
<div class="flex-row-center p-1">
Command benchmark {avgTime / opss}
{maxTime} - {active}
Command benchmark {Math.round((avgTime / opss) * 100) / 100}
{Math.round(maxTime * 100) / 100} - {active}
</div>
<div class="flex-row-center p-1">
<div class="flex-row-center p-1">
@ -230,7 +230,7 @@
void fetch(endpoint + `/api/v1/manage?token=${token}&operation=profile-start`, {
method: 'PUT'
})
fetchStats(0)
void fetchStats(0)
}}
/>
{:else}

View File

@ -15,14 +15,16 @@
Object.keys(metrics.params).length > 0 ||
(metrics.topResult?.length ?? 0) > 0
const toTime = (value: number, digits = 10): number => Math.round(value * digits) / digits
function showAvg (name: string, time: number, ops: number): string {
if (name.startsWith('#')) {
return `➿ ${time}`
return `➿ ${toTime(time)}`
}
if (ops === 0) {
return `⏱️ ${time}`
return `⏱️ ${toTime(time)}`
}
return `${Math.floor((time / ops) * 100) / 100}`
return `${toTime(time / ops, 100)}`
}
const getSorted = (v: Record<string, MetricsData>, sortingOrder: 'avg' | 'ops' | 'total') => {
if (sortingOrder === 'avg') {
@ -87,7 +89,7 @@
</FixedColumn>
<FixedColumn key="time-full">
<span class="p-1">
{metrics.value}
{toTime(metrics.value)}
</span>
</FixedColumn>
</div>
@ -98,14 +100,14 @@
<Expandable>
<svelte:fragment slot="title">
<div class="flex-row-center flex-between flex-grow ml-2">
Slowest result:{metrics.topResult[0].value}
Slowest result:{toTime(metrics.topResult[0].value)}
</div>
</svelte:fragment>
{#each metrics.topResult ?? [] as r}
<Expandable>
<svelte:fragment slot="title">
<div class="flex-row-center flex-between flex-grow select-text">
Time:{r.value}
Time:{toTime(r.value)}
</div>
</svelte:fragment>
<pre class="select-text">
@ -142,7 +144,7 @@
<FixedColumn key="time">
{showAvg(kk, vv.value, vv.operations)}
</FixedColumn>
<FixedColumn key="time-full">{vv.value}</FixedColumn>
<FixedColumn key="time-full">{toTime(vv.value)}</FixedColumn>
</div>
</FixedColumn>
</svelte:fragment>
@ -152,7 +154,7 @@
<Expandable>
<svelte:fragment slot="title">
<div class="flex-row-center flex-between flex-grow">
Time:{r.value}
Time:{toTime(r.value)}
</div>
</svelte:fragment>
<pre class="select-text">

View File

@ -60,7 +60,7 @@ const activeQueries = new Map<number, { time: number, cancel: () => void, query:
setInterval(() => {
for (const [k, v] of activeQueries.entries()) {
if (Date.now() - v.time > tickTimeout) {
if (performance.now() - v.time > tickTimeout) {
console.log('query hang', k, v)
v.cancel()
activeQueries.delete(k)
@ -88,17 +88,17 @@ async function handleSQLFind (
response.writeHead(403).end('Not allowed')
return
}
const st = Date.now()
const st = performance.now()
const query = sql.unsafe(json.query, json.params, { prepare: true })
activeQueries.set(qid, {
time: Date.now(),
time: performance.now(),
cancel: () => {
query.cancel()
},
query: json.query
})
const result = await query
const qtime = Date.now() - st
const qtime = performance.now() - st
console.log('query', json.query, qtime, result.length)
await toResponse(compression, result, response, qtime)
} catch (err: any) {

View File

@ -61,7 +61,8 @@ import core, {
type TxRemoveDoc,
type TxResult,
type TxUpdateDoc,
type WithLookup
type WithLookup,
platformNow
} from '@hcengineering/core'
import {
type DbAdapter,
@ -647,7 +648,7 @@ abstract class MongoAdapterBase implements DbAdapter {
options: ServerFindOptions<T>,
stTime: number
): Promise<FindResult<T>> {
const st = Date.now()
const st = platformNow()
const pipeline: any[] = []
const tquery = this.translateQuery(clazz, query, options)
@ -760,7 +761,7 @@ abstract class MongoAdapterBase implements DbAdapter {
)
total = arr?.[0]?.total ?? 0
}
const edTime = Date.now()
const edTime = platformNow()
if (edTime - stTime > 1000 || st - stTime > 1000) {
ctx.error('aggregate', {
time: edTime - stTime,
@ -892,11 +893,11 @@ abstract class MongoAdapterBase implements DbAdapter {
query: DocumentQuery<T>,
options?: ServerFindOptions<T>
): Promise<FindResult<T>> {
const stTime = Date.now()
const stTime = platformNow()
const mongoQuery = this.translateQuery(_class, query, options)
const fQuery = { ...mongoQuery.base, ...mongoQuery.lookup }
return addOperation(ctx, 'find-all', {}, async () => {
const st = Date.now()
const st = platformNow()
let result: FindResult<T>
const domain = options?.domain ?? this.hierarchy.getDomain(_class)
if (
@ -994,7 +995,7 @@ abstract class MongoAdapterBase implements DbAdapter {
throw e
}
const edTime = Date.now()
const edTime = platformNow()
if (edTime - st > 1000 || st - stTime > 1000) {
ctx.error('FindAll', {
time: edTime - st,
@ -1222,8 +1223,8 @@ class MongoAdapter extends MongoAdapterBase {
return undefined
})
const stTime = Date.now()
const st = Date.now()
const stTime = platformNow()
const st = stTime
let promises: Promise<any>[] = []
for (const [domain, txs] of byDomain) {
if (domain === undefined) {
@ -1319,7 +1320,7 @@ class MongoAdapter extends MongoAdapterBase {
'find-result',
{},
async (ctx) => {
const st = Date.now()
const st = platformNow()
const docs = await addOperation(
ctx,
'find-result',

View File

@ -1,4 +1,4 @@
import { concatLink } from '@hcengineering/core'
import { concatLink, platformNow } from '@hcengineering/core'
import type postgres from 'postgres'
import type { ParameterOrJSON } from 'postgres'
import { convertArrayParams, doFetchTypes, getPrepare } from './utils'
@ -50,7 +50,7 @@ class GreenClient implements DBClient {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const st = Date.now()
const st = platformNow()
const response = await fetch(this.endpoint, {
method: 'POST',
headers: {
@ -84,7 +84,7 @@ class GreenClient implements DBClient {
return await response.json()
} finally {
const qtime = response.headers.get('querytime')
const time = Date.now() - st
const time = platformNow() - st
console.info({
message: `green query: ${time} ${qtime ?? 0}`,
query,

View File

@ -24,6 +24,8 @@ import core, {
generateId,
type MeasureContext,
type MixinUpdate,
platformNow,
platformNowDiff,
type Projection,
type Ref,
systemAccountUuid,
@ -78,7 +80,7 @@ export async function createTables (
return
}
const mapped = filtered.map((p) => translateDomain(p))
const t = Date.now()
const t = platformNow()
loadedTables =
loadedTables.size === 0
? new Set(
@ -96,7 +98,7 @@ export async function createTables (
).map((it) => it.table_name)
)
: loadedTables
console.log('load-table', Date.now() - t)
console.log('load-table', platformNowDiff(t))
const domainsToLoad = mapped.filter((it) => loadedTables.has(it))
if (domainsToLoad.length > 0) {

View File

@ -40,7 +40,9 @@ import core, {
type WorkspaceDataId,
type PersonUuid,
Data,
Version
Version,
platformNow,
platformNowDiff
} from '@hcengineering/core'
import { getClient as getAccountClient, isWorkspaceLoginInfo } from '@hcengineering/account-client'
import { unknownError, type Status } from '@hcengineering/platform'
@ -984,7 +986,7 @@ class TSessionManager implements SessionManager {
ws: ConnectionSocket,
workspace: WorkspaceUuid
): ClientSessionCtx {
const st = Date.now()
const st = platformNow()
return {
ctx,
pipeline,
@ -993,7 +995,7 @@ class TSessionManager implements SessionManager {
sendResponse(ctx, service, ws, {
id: reqId,
result: msg,
time: Date.now() - st,
time: platformNowDiff(st),
bfst: Date.now(),
queue: service.requests.size
}),
@ -1006,7 +1008,7 @@ class TSessionManager implements SessionManager {
id: reqId,
result: msg,
error,
time: Date.now() - st,
time: platformNowDiff(st),
bfst: Date.now(),
queue: service.requests.size
})
@ -1046,7 +1048,7 @@ class TSessionManager implements SessionManager {
// Calculate total number of clients
const reqId = generateId()
const st = Date.now()
const st = platformNow()
return userCtx
.with('🧭 handleRequest', {}, async (ctx) => {
if (request.time != null) {

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
import { AccountClient } from '@hcengineering/account-client'
import core, {
Branding,
coreId,
@ -26,19 +27,20 @@ import core, {
MeasureContext,
MigrationState,
ModelDb,
platformNow,
platformNowDiff,
systemAccountUuid,
Tx,
TxOperations,
WorkspaceUuid,
WorkspaceIds,
WorkspaceUuid,
type Client,
type PersonInfo,
type Ref,
type WithLookup,
type PersonInfo
type WithLookup
} from '@hcengineering/core'
import { consoleModelLogger, MigrateOperation, ModelLogger, tryMigrate } from '@hcengineering/model'
import { DomainIndexHelperImpl, Pipeline, StorageAdapter, type DbAdapter } from '@hcengineering/server-core'
import { AccountClient } from '@hcengineering/account-client'
import { InitScript, WorkspaceInitializer } from './initializer'
import toolPlugin from './plugin'
import { MigrateClientImpl } from './upgrade'
@ -164,10 +166,10 @@ export async function updateModel (
try {
let i = 0
for (const op of migrateOperations) {
const st = Date.now()
const st = platformNow()
await op[1].upgrade(migrateState, async () => connection as any, logger)
const tdelta = Date.now() - st
if (tdelta > 0) {
const tdelta = platformNowDiff(st)
if (tdelta > 0.5) {
logger.log('Create', { name: op[0], time: tdelta })
}
i++
@ -272,14 +274,14 @@ export async function upgradeModel (
}
const preMigrate = op[1].preMigrate
const t = Date.now()
const t = platformNow()
try {
await ctx.with(op[0], {}, (ctx) => preMigrate(preMigrateClient, logger))
} catch (err: any) {
logger.error(`error during pre-migrate: ${op[0]} ${err.message}`, err)
throw err
}
logger.log('pre-migrate:', { workspaceId: wsIds, operation: op[0], time: Date.now() - t })
logger.log('pre-migrate:', { workspaceId: wsIds, operation: op[0], time: platformNowDiff(t) })
await progress(((100 / migrateOperations.length) * i * 10) / 100)
i++
}
@ -317,11 +319,11 @@ export async function upgradeModel (
let i = 0
for (const op of migrateOperations) {
try {
const t = Date.now()
const t = platformNow()
await ctx.with(op[0], {}, () => op[1].migrate(migrateClient, logger))
const tdelta = Date.now() - t
const tdelta = platformNowDiff(t)
if (tdelta > 0) {
logger.log('migrate:', { workspaceId: wsIds, operation: op[0], time: Date.now() - t })
logger.log('migrate:', { workspaceId: wsIds, operation: op[0], time: tdelta })
}
} catch (err: any) {
logger.error(`error during migrate: ${op[0]} ${err.message}`, err)

View File

@ -13,14 +13,19 @@
// limitations under the License.
//
import {
getClient as getAccountClientRaw,
isWorkspaceLoginInfo,
type AccountClient
} from '@hcengineering/account-client'
import { Analytics } from '@hcengineering/analytics'
import {
generateId,
systemAccountUuid,
type WorkspaceUuid,
type MeasureContext,
type Tx,
type WorkspaceIds
type WorkspaceIds,
type WorkspaceUuid
} from '@hcengineering/core'
import platform, { Severity, Status, UNAUTHORIZED, unknownStatus } from '@hcengineering/platform'
import { RPCHandler, type Response } from '@hcengineering/rpc'
@ -34,11 +39,6 @@ import {
type BlobResponse,
type WebsocketData
} from '@hcengineering/server'
import {
getClient as getAccountClientRaw,
isWorkspaceLoginInfo,
type AccountClient
} from '@hcengineering/account-client'
import {
LOGGING_ENABLED,
pingConst,
@ -51,7 +51,7 @@ import {
} from '@hcengineering/server-core'
import { decodeToken, type Token } from '@hcengineering/server-token'
import cors from 'cors'
import express, { type NextFunction, type Request, type Response as ExpressResponse } from 'express'
import express, { type Response as ExpressResponse, type NextFunction, type Request } from 'express'
import http, { type IncomingMessage } from 'http'
import os from 'os'
import { WebSocketServer, type RawData, type WebSocket } from 'ws'
@ -641,15 +641,11 @@ function createWebsocketClientSocket (
},
send: (ctx: MeasureContext, msg, binary, _compression) => {
const smsg = rpcHandler.serialize(msg, binary)
ctx.measure('send-data', smsg.length)
const st = Date.now()
if (ws.readyState !== ws.OPEN || cs.isClosed) {
return
}
const handleErr = (err?: Error): void => {
ctx.measure('msg-send-delta', Date.now() - st)
if (err != null) {
if (!`${err.message}`.includes('WebSocket is not open')) {
ctx.error('send error', { err })

View File

@ -3,6 +3,8 @@
import {
generateId,
NoMetricsContext,
platformNow,
platformNowDiff,
WorkspaceUuid,
type Account,
type Class,
@ -216,11 +218,11 @@ export class Transactor extends DurableObject<Env> {
s.context.measure('receive-data', buff?.length ?? 0)
// processRequest(s.session, cs, s.context, s.workspaceId, buff, handleRequest)
const request = cs.readRequest(buff, s.session.binaryMode)
const st = Date.now()
const st = platformNow()
const r = this.sessionManager.handleRequest(this.measureCtx, s.session, cs, request, this.workspace)
this.ctx.waitUntil(
r.finally(() => {
const time = Date.now() - st
const time = platformNowDiff(st)
console.log({
message: `handle-request: ${request.method} time: ${time}`,
method: request.method,