diff --git a/.vscode/launch.json b/.vscode/launch.json index 090cdf176a..7c1bf86405 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -100,6 +100,7 @@ "ACCOUNTS_URL": "http://localhost:3000", "UPLOAD_URL": "/files", "SERVER_PORT": "8087", + "VERSION": null, "COLLABORATOR_URL": "ws://localhost:3078", "COLLABORATOR_API_URL": "http://localhost:3078", "CALENDAR_URL": "http://localhost:8095", diff --git a/common/scripts/version.txt b/common/scripts/version.txt index 0fa1e44bad..2974978539 100644 --- a/common/scripts/version.txt +++ b/common/scripts/version.txt @@ -1 +1 @@ -"0.6.270" \ No newline at end of file +"0.6.271" \ No newline at end of file diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index d8fb0b1c6d..23377590e8 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -77,6 +77,7 @@ services: - ACCOUNTS_URL=http://account:3000 - UPLOAD_URL=/files - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - 'MONGO_OPTIONS={"appName":"collaborator","maxPoolSize":2}' - STORAGE_CONFIG=${STORAGE_CONFIG} restart: unless-stopped front: @@ -95,6 +96,7 @@ services: - SERVER_PORT=8080 - SERVER_SECRET=secret - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - 'MONGO_OPTIONS={"appName":"front","maxPoolSize":1}' - ACCOUNTS_URL=http://localhost:3000 - UPLOAD_URL=/files - ELASTIC_URL=http://elastic:9200 @@ -135,6 +137,7 @@ services: - ENABLE_COMPRESSION=true - ELASTIC_URL=http://elastic:9200 - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - 'MONGO_OPTIONS={"appName": "transactor", "maxPoolSize": 1}' - METRICS_CONSOLE=false - METRICS_FILE=metrics.txt - STORAGE_CONFIG=${STORAGE_CONFIG} @@ -165,6 +168,7 @@ services: environment: - SECRET=secret - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - 'MONGO_OPTIONS={"appName":"print","maxPoolSize":1}' - STORAGE_CONFIG=${STORAGE_CONFIG} deploy: resources: @@ -181,6 +185,7 @@ services: environment: - SECRET=secret - MONGO_URL=mongodb://mongodb:27017 + - 'MONGO_OPTIONS={"appName":"sign","maxPoolSize":1}' - MINIO_ENDPOINT=minio - MINIO_ACCESS_KEY=minioadmin - ACCOUNTS_URL=http://account:3000 @@ -201,6 +206,7 @@ services: - SECRET=secret - PORT=4007 - MONGO_URL=mongodb://mongodb:27017 + - 'MONGO_OPTIONS={"appName":"analytics","maxPoolSize":1}' - SERVICE_ID=analytics-collector-service - ACCOUNTS_URL=http://account:3000 - SUPPORT_WORKSPACE=support diff --git a/dev/prod/public/config.json b/dev/prod/public/config.json index 97c6971b9b..46d9f904a3 100644 --- a/dev/prod/public/config.json +++ b/dev/prod/public/config.json @@ -15,6 +15,6 @@ "SIGN_URL": "http://localhost:4006", "ANALYTICS_COLLECTOR_URL": "http://localhost:4077", "BRANDING_URL": "/branding.json", - "VERSION": "0.6.266", - "MODEL_VERSION": "0.6.266" + "VERSION": null, + "MODEL_VERSION": null } \ No newline at end of file diff --git a/models/core/src/security.ts b/models/core/src/security.ts index c4934e58c0..fa694867e3 100644 --- a/models/core/src/security.ts +++ b/models/core/src/security.ts @@ -70,6 +70,7 @@ export class TSpace extends TDoc implements Space { archived!: boolean @Prop(ArrOf(TypeRef(core.class.Account)), core.string.Members) + @Index(IndexKind.Indexed) members!: Arr> @Prop(ArrOf(TypeRef(core.class.Account)), core.string.Owners) diff --git a/models/preference/src/index.ts b/models/preference/src/index.ts index c6cfc8477b..0e2ae21cae 100644 --- a/models/preference/src/index.ts +++ b/models/preference/src/index.ts @@ -39,6 +39,6 @@ export function createModel (builder: Builder): void { builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, { domain: DOMAIN_PREFERENCE, - disabled: [{ modifiedOn: 1 }, { createdOn: 1 }] + disabled: [{ modifiedOn: 1 }, { createdOn: 1 }, { attachedTo: 1 }, { createdOn: -1 }, { modifiedBy: 1 }] }) } diff --git a/models/tags/src/index.ts b/models/tags/src/index.ts index 64a2531fc2..ffc707da9b 100644 --- a/models/tags/src/index.ts +++ b/models/tags/src/index.ts @@ -148,6 +148,7 @@ export function createModel (builder: Builder): void { builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, { domain: DOMAIN_TAGS, disabled: [ + { _class: 1 }, { modifiedOn: 1 }, { modifiedBy: 1 }, { createdBy: 1 }, diff --git a/packages/core/src/measurements/metrics.ts b/packages/core/src/measurements/metrics.ts index fbef8f77f9..d3a9ae014d 100644 --- a/packages/core/src/measurements/metrics.ts +++ b/packages/core/src/measurements/metrics.ts @@ -1,7 +1,6 @@ // Basic performance metrics suite. import { MetricsData } from '.' -import { cutObjectArray } from '../utils' import { FullParamsType, Metrics, ParamsType } from './types' /** @@ -35,7 +34,7 @@ function getUpdatedTopResult ( const newValue = { value: time, - params: cutObjectArray(params) + params } if (result.length > 6) { diff --git a/packages/core/src/operations.ts b/packages/core/src/operations.ts index 94e45c3ec9..4c70d569a7 100644 --- a/packages/core/src/operations.ts +++ b/packages/core/src/operations.ts @@ -487,9 +487,13 @@ export class ApplyOperations extends TxOperations { extraNotify ) )) as Promise) + const dnow = Date.now() + if (typeof window === 'object' && window !== null) { + console.log(`measure ${this.measureName}`, dnow - st, 'server time', result.serverTime) + } return { result: result.success, - time: Date.now() - st, + time: dnow - st, serverTime: result.serverTime } } diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 2fe36d2e10..075f0f535e 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -13,8 +13,9 @@ // limitations under the License. // -import { getEmbeddedLabel, IntlString } from '@hcengineering/platform' +import { getEmbeddedLabel, IntlString, PlatformError, unknownError } from '@hcengineering/platform' import { deepEqual } from 'fast-equals' +import { DOMAIN_BENCHMARK } from './benchmark' import { Account, AccountRole, @@ -46,7 +47,6 @@ import { TxOperations } from './operations' import { isPredicate } from './predicate' import { DocumentQuery, FindResult } from './storage' import { DOMAIN_TX } from './tx' -import { DOMAIN_BENCHMARK } from './benchmark' function toHex (value: number, chars: number): string { const result = value.toString(16) @@ -355,7 +355,6 @@ export class DocManager implements IDocManager { export class RateLimiter { idCounter: number = 0 - processingQueue = new Map>() last: number = 0 rate: number @@ -366,21 +365,21 @@ export class RateLimiter { } notify: (() => void)[] = [] + finished: boolean = false async exec = any>(op: (args?: B) => Promise, args?: B): Promise { - const processingId = this.idCounter++ - - while (this.processingQueue.size >= this.rate) { + if (this.finished) { + throw new PlatformError(unknownError('No Possible to add/exec on finished queue')) + } + while (this.notify.length >= this.rate) { await new Promise((resolve) => { this.notify.push(resolve) }) } try { const p = op(args) - this.processingQueue.set(processingId, p as Promise) return await p } finally { - this.processingQueue.delete(processingId) const n = this.notify.shift() if (n !== undefined) { n() @@ -389,7 +388,7 @@ export class RateLimiter { } async add = any>(op: (args?: B) => Promise, args?: B): Promise { - if (this.processingQueue.size < this.rate) { + if (this.notify.length < this.rate) { void this.exec(op, args) } else { await this.exec(op, args) @@ -397,7 +396,12 @@ export class RateLimiter { } async waitProcessing (): Promise { - await Promise.all(this.processingQueue.values()) + this.finished = true + while (this.notify.length > 0) { + await new Promise((resolve) => { + this.notify.push(resolve) + }) + } } } diff --git a/packages/platform-rig/profiles/ui/config/rush-project.json b/packages/platform-rig/profiles/ui/config/rush-project.json index 4b6cf6cfde..b1a8f0c8c5 100644 --- a/packages/platform-rig/profiles/ui/config/rush-project.json +++ b/packages/platform-rig/profiles/ui/config/rush-project.json @@ -3,7 +3,6 @@ "temp/**", ".build/**", "coverage/**", - "**/*.svelte", ".build/**", ".validate/**", ".format/**", diff --git a/packages/platform/src/i18n.ts b/packages/platform/src/i18n.ts index b59fb3c78a..e70869bde5 100644 --- a/packages/platform/src/i18n.ts +++ b/packages/platform/src/i18n.ts @@ -31,8 +31,8 @@ export type Loader = (locale: string) => Promise> const loaders = new Map() -const translations = new Map() -const cache = new Map() +const translations = new Map>() +const cache = new Map>() const englishTranslationsForMissing = new Map() /** * @public @@ -52,10 +52,14 @@ export async function loadPluginStrings (locale: string, force: boolean = false) cache.clear() } for (const [plugin] of loaders) { - let messages = translations.get(plugin) + const localtTanslations = translations.get(locale) ?? new Map>() + if (!translations.has(locale)) { + translations.set(locale, localtTanslations) + } + let messages = localtTanslations.get(plugin) if (messages === undefined || force) { messages = await loadTranslationsForComponent(plugin, locale) - translations.set(plugin, messages) + localtTanslations.set(plugin, messages) } } } @@ -83,10 +87,14 @@ async function loadTranslationsForComponent (plugin: Plugin, locale: string): Pr async function getTranslation (id: _IdInfo, locale: string): Promise { try { - let messages = translations.get(id.component) + const localtTanslations = translations.get(locale) ?? new Map>() + if (!translations.has(locale)) { + translations.set(locale, localtTanslations) + } + let messages = localtTanslations.get(id.component) if (messages === undefined) { messages = await loadTranslationsForComponent(id.component, locale) - translations.set(id.component, messages) + localtTanslations.set(id.component, messages) } if (messages instanceof Status) { return messages @@ -127,7 +135,11 @@ export async function translate

> ( language?: string ): Promise { const locale = language ?? getMetadata(platform.metadata.locale) ?? 'en' - const compiled = cache.get(message) + const localCache = cache.get(locale) ?? new Map() + if (!cache.has(locale)) { + cache.set(locale, localCache) + } + const compiled = localCache.get(message) if (compiled !== undefined) { if (compiled instanceof Status) { @@ -142,16 +154,16 @@ export async function translate

> ( } const translation = (await getTranslation(id, locale)) ?? message if (translation instanceof Status) { - cache.set(message, translation) + localCache.set(message, translation) return message } const compiled = new IntlMessageFormat(translation, locale, undefined, { ignoreTag: true }) - cache.set(message, compiled) + localCache.set(message, compiled) return compiled.format(params) } catch (err) { const status = unknownError(err) await setPlatformStatus(status) - cache.set(message, status) + localCache.set(message, status) return message } } diff --git a/packages/presentation/src/components/DocPopup.svelte b/packages/presentation/src/components/DocPopup.svelte index 1e79379189..e5799c6bef 100644 --- a/packages/presentation/src/components/DocPopup.svelte +++ b/packages/presentation/src/components/DocPopup.svelte @@ -190,6 +190,7 @@ {size} icon={IconAdd} showTooltip={{ label: create.label }} + dataId={'btnAdd'} on:click={onCreate} disabled={readonly || loading} /> diff --git a/packages/presentation/src/components/FilePreview.svelte b/packages/presentation/src/components/FilePreview.svelte index 4397b1173c..00988014c5 100644 --- a/packages/presentation/src/components/FilePreview.svelte +++ b/packages/presentation/src/components/FilePreview.svelte @@ -13,18 +13,18 @@ // limitations under the License. -->

{:else if previewType !== undefined} - + {:else}