UBERF-7489: Fix various performance issues (#5983)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-07-03 15:16:04 +07:00 committed by GitHub
parent 9d3ce44ce7
commit d5a83391c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 37 deletions

View File

@ -21,7 +21,6 @@ import core, {
concatLink,
getCurrentAccount,
reduceCalls,
type TxApplyIf,
type AnyAttribute,
type ArrOf,
type AttachedDoc,
@ -46,10 +45,11 @@ import core, {
type SearchResult,
type Space,
type Tx,
type TxApplyIf,
type TxCUD,
type TxResult,
type TypeAny,
type WithLookup,
type TxCUD
type WithLookup
} from '@hcengineering/core'
import { getMetadata, getResource } from '@hcengineering/platform'
import { LiveQuery as LQ } from '@hcengineering/query'
@ -57,13 +57,14 @@ import { getRawCurrentLocation, workspaceId, type AnyComponent, type AnySvelteCo
import view, { type AttributeCategory, type AttributeEditor } from '@hcengineering/view'
import { deepEqual } from 'fast-equals'
import { onDestroy } from 'svelte'
import { type Writable, get, writable } from 'svelte/store'
import { get, writable, type Writable } from 'svelte/store'
import { type KeyedAttribute } from '..'
import { OptimizeQueryMiddleware, PresentationPipelineImpl, type PresentationPipeline } from './pipeline'
import plugin from './plugin'
export { reduceCalls } from '@hcengineering/core'
let liveQuery: LQ
let rawLiveQuery: LQ
let client: TxOperations & MeasureClient & OptimisticTxes
let pipeline: PresentationPipeline
@ -76,6 +77,10 @@ export function addTxListener (l: (tx: Tx) => void): void {
txListeners.push(l)
}
export function getRawLiveQuery (): LQ {
return rawLiveQuery
}
/**
* @public
*/
@ -144,6 +149,8 @@ class UIClient extends TxOperations implements Client, MeasureClient, Optimistic
await liveQuery.tx(...tx)
await rawLiveQuery.tx(...tx)
txListeners.forEach((it) => {
it(...tx)
})
@ -250,17 +257,24 @@ export async function setClient (_client: MeasureClient): Promise<void> {
if (liveQuery !== undefined) {
await liveQuery.close()
}
if (rawLiveQuery !== undefined) {
await rawLiveQuery.close()
}
if (pipeline !== undefined) {
await pipeline.close()
}
const needRefresh = liveQuery !== undefined
rawLiveQuery = new LQ(_client)
const factories = await _client.findAll(plugin.class.PresentationMiddlewareFactory, {})
const promises = factories.map(async (it) => await getResource(it.createPresentationMiddleware))
const creators = await Promise.all(promises)
// eslint-disable-next-line @typescript-eslint/unbound-method
pipeline = PresentationPipelineImpl.create(_client, [OptimizeQueryMiddleware.create, ...creators])
const needRefresh = liveQuery !== undefined
liveQuery = new LQ(pipeline)
const uiClient = new UIClient(pipeline, liveQuery)
client = uiClient

View File

@ -406,7 +406,27 @@
$: projectPreferences.query(tracker.class.ProjectTargetPreference, {}, (res) => {
preferences = res
})
$: spacePreferences = preferences.find((it) => it.attachedTo === _space)
async function updateCurrentProjectPref (currentProject: Ref<Project>): Promise<void> {
const spacePreferences = await client.findOne(tracker.class.ProjectTargetPreference, { attachedTo: currentProject })
if (spacePreferences === undefined) {
await client.createDoc(tracker.class.ProjectTargetPreference, currentProject, {
attachedTo: currentProject,
props: [],
usedOn: Date.now()
})
} else {
if (spacePreferences.usedOn + 60 * 1000 < Date.now()) {
await client.update(spacePreferences, {
usedOn: Date.now()
})
}
}
}
$: if (_space !== undefined) {
void updateCurrentProjectPref(_space)
}
async function createIssue (): Promise<void> {
const _id: Ref<Issue> = generateId()
@ -713,24 +733,6 @@
originalIssue,
preferences
}
function updateCurrentProjectPref (currentProject: Ref<Project>): void {
if (spacePreferences === undefined) {
void client.createDoc(tracker.class.ProjectTargetPreference, currentProject, {
attachedTo: currentProject,
props: [],
usedOn: Date.now()
})
} else {
void client.update(spacePreferences, {
usedOn: Date.now()
})
}
}
$: if (_space !== undefined) {
updateCurrentProjectPref(_space)
}
</script>
<FocusHandler {manager} />

View File

@ -18,12 +18,15 @@ import { Analytics } from '@hcengineering/analytics'
import core, {
AccountRole,
ClassifierKind,
DocManager,
Hierarchy,
SortingOrder,
TxProcessor,
getCurrentAccount,
getObjectValue,
type Account,
type AggregateValue,
type AnyAttribute,
type AttachedDoc,
type CategoryType,
type Class,
@ -42,6 +45,7 @@ import core, {
type ReverseLookup,
type ReverseLookups,
type Space,
type Tx,
type TxCUD,
type TxCollectionCUD,
type TxCreateDoc,
@ -50,11 +54,7 @@ import core, {
type TxUpdateDoc,
type TypeAny,
type TypedSpace,
type WithLookup,
type AnyAttribute,
DocManager,
SortingOrder,
type Tx
type WithLookup
} from '@hcengineering/core'
import { type Restrictions } from '@hcengineering/guest'
import type { Asset, IntlString } from '@hcengineering/platform'
@ -64,11 +64,11 @@ import {
getAttributePresenterClass,
getClient,
getFiltredKeys,
getRawLiveQuery,
hasResource,
isAdminUser,
type KeyedAttribute
} from '@hcengineering/presentation'
import { LiveQuery } from '@hcengineering/query'
import { type CollaborationUser } from '@hcengineering/text-editor'
import {
ErrorPresenter,
@ -85,7 +85,6 @@ import {
type Location
} from '@hcengineering/ui'
import view, {
type IAggregationManager,
AttributeCategoryOrder,
type AttributeCategory,
type AttributeModel,
@ -93,9 +92,10 @@ import view, {
type BuildModelKey,
type BuildModelOptions,
type CollectionPresenter,
type IAggregationManager,
type LinkIdProvider,
type Viewlet,
type ViewletDescriptor,
type LinkIdProvider
type ViewletDescriptor
} from '@hcengineering/view'
import contact, { getName, type Contact, type PersonAccount } from '@hcengineering/contact'
@ -119,7 +119,6 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
docs: T[] | undefined
mgr: DocManager<T> | Promise<DocManager<T>> | undefined
query: (() => void) | undefined
lq: LiveQuery
lqCallback: () => void
private readonly setStore: (manager: DocManager<T>) => void
private readonly filter: (doc: T, target: T) => boolean
@ -132,7 +131,6 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
categorizingFunc: (doc: T, target: T) => boolean,
_class: Ref<Class<T>>
) {
this.lq = new LiveQuery(client)
this.lqCallback = lqCallback ?? (() => {})
this.setStore = setStore
this.filter = categorizingFunc
@ -158,7 +156,7 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
return this.mgr
}
this.mgr = new Promise<DocManager<T>>((resolve) => {
this.query = this.lq.query(
this.query = getRawLiveQuery().query(
this._class,
{},
(res) => {
@ -187,7 +185,7 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
}
async notifyTx (...tx: Tx[]): Promise<void> {
await this.lq.tx(...tx)
// This is intentional
}
getAttrClass (): Ref<Class<T>> {