From 4cd3895735adb05f2893e32024fb73f5a448a4f3 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Thu, 14 Sep 2023 13:10:05 +0700 Subject: [PATCH] UBER-834: Improve list speed Signed-off-by: Andrey Sobolev --- models/recruit/src/index.ts | 101 ++++++++++++++++- models/recruit/src/plugin.ts | 2 + packages/core/src/utils.ts | 44 ++++++++ .../src/components/icons/CollapseArrow.svelte | 2 +- .../src/components/Organizations.svelte | 77 ++++++------- .../src/components/list/List.svelte | 40 ++++++- .../src/components/list/ListCategories.svelte | 13 ++- .../src/components/list/ListCategory.svelte | 104 ++++++++++-------- .../src/components/list/ListHeader.svelte | 6 +- server/core/src/limitter.ts | 44 +------- 10 files changed, 299 insertions(+), 134 deletions(-) diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 4b513b2496..d452298fa8 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -676,7 +676,7 @@ export function createModel (builder: Builder): void { const applicantViewOptions = (colors: boolean): ViewOptionsModel => { const model: ViewOptionsModel = { - groupBy: ['status', 'assignee', 'space', 'createdBy', 'modifiedBy'], + groupBy: ['status', 'doneState', 'assignee', 'space', 'createdBy', 'modifiedBy'], orderBy: [ ['status', SortingOrder.Ascending], ['modifiedOn', SortingOrder.Descending], @@ -784,6 +784,105 @@ export function createModel (builder: Builder): void { recruit.viewlet.ListApplicant ) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: recruit.mixin.Candidate, + descriptor: view.viewlet.List, + config: [ + { key: '', displayProps: { fixed: 'left', key: 'app' } }, + { + key: 'title', + props: { kind: 'list', size: 'small', shouldShowName: false } + }, + { key: 'comments', displayProps: { key: 'comments', suffix: true } }, + { key: '', displayProps: { grow: true } }, + { + key: '$lookup.channels', + label: contact.string.ContactInfo, + sortingKey: ['$lookup.channels.lastMessage', '$lookup.attachedTo.channels'], + props: { + length: 'full', + size: 'small', + kind: 'list' + }, + displayProps: { compression: true } + }, + { key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } } + ], + configOptions: { + strict: true, + hiddenKeys: ['name'] + }, + viewOptions: { + groupBy: ['createdBy', 'modifiedBy'], + orderBy: [ + ['modifiedOn', SortingOrder.Descending], + ['createdOn', SortingOrder.Descending], + ['rank', SortingOrder.Ascending] + ], + other: [showColorsViewOption] + } + }, + recruit.viewlet.ListTalent + ) + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: recruit.mixin.VacancyList, + descriptor: view.viewlet.List, + config: [ + { key: '', displayProps: { fixed: 'left', key: 'app' } }, + { + key: '@vacancies', + label: recruit.string.Vacancies, + props: { kind: 'list', size: 'small', shouldShowName: false } + }, + { + key: '@applications', + label: recruit.string.Applications, + props: { kind: 'list', size: 'small', shouldShowName: false } + }, + { key: 'comments', displayProps: { key: 'comments', suffix: true } }, + { + key: '$lookup.channels', + label: contact.string.ContactInfo, + sortingKey: ['$lookup.channels.lastMessage', '$lookup.attachedTo.channels'], + props: { + length: 'full', + size: 'small', + kind: 'list' + }, + displayProps: { compression: true } + }, + { key: '', displayProps: { grow: true } }, + { + key: '@applications.modifiedOn', + label: core.string.ModifiedDate, + displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } + } + ], + configOptions: { + strict: true, + sortable: true, + hiddenKeys: ['name', 'space', 'modifiedOn'] + }, + viewOptions: { + groupBy: ['createdBy', 'modifiedBy'], + orderBy: [ + ['modifiedOn', SortingOrder.Descending], + ['createdOn', SortingOrder.Descending], + ['rank', SortingOrder.Ascending] + ], + other: [showColorsViewOption] + } + }, + recruit.viewlet.ListCompanies + ) + builder.createDoc( view.class.Viewlet, core.space.Model, diff --git a/models/recruit/src/plugin.ts b/models/recruit/src/plugin.ts index 3265e492dc..be6bb21a9e 100644 --- a/models/recruit/src/plugin.ts +++ b/models/recruit/src/plugin.ts @@ -120,6 +120,8 @@ export default mergeIds(recruitId, recruit, { ApplicantTable: '' as Ref, ApplicantKanban: '' as Ref, ListApplicant: '' as Ref, + ListTalent: '' as Ref, + ListCompanies: '' as Ref, TableApplicant: '' as Ref, TableApplicantMatch: '' as Ref, CalendarReview: '' as Ref, diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 94f5294dcc..8dcc75df67 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -280,3 +280,47 @@ export class DocManager { return this.docs.filter(predicate) } } + +/** + * @public + */ + +export class RateLimitter { + idCounter: number = 0 + processingQueue = new Map>() + last: number = 0 + + queue: (() => Promise)[] = [] + + constructor (readonly config: () => { rate: number, perSecond?: number }) {} + + async exec = {}>(op: (args?: B) => Promise, args?: B): Promise { + const processingId = `${this.idCounter++}` + const cfg = this.config() + + while (this.processingQueue.size > cfg.rate) { + await Promise.race(this.processingQueue.values()) + } + try { + const p = op(args) + this.processingQueue.set(processingId, p as Promise) + return await p + } finally { + this.processingQueue.delete(processingId) + } + } + + async add = {}>(op: (args?: B) => Promise, args?: B): Promise { + const cfg = this.config() + + if (this.processingQueue.size < cfg.rate) { + void this.exec(op, args) + } else { + await this.exec(op, args) + } + } + + async waitProcessing (): Promise { + await await Promise.race(this.processingQueue.values()) + } +} diff --git a/packages/ui/src/components/icons/CollapseArrow.svelte b/packages/ui/src/components/icons/CollapseArrow.svelte index dd863e4a8d..e1a07b7f47 100644 --- a/packages/ui/src/components/icons/CollapseArrow.svelte +++ b/packages/ui/src/components/icons/CollapseArrow.svelte @@ -1,5 +1,5 @@ diff --git a/plugins/recruit-resources/src/components/Organizations.svelte b/plugins/recruit-resources/src/components/Organizations.svelte index 30ecc244a8..c92d28ef2b 100644 --- a/plugins/recruit-resources/src/components/Organizations.svelte +++ b/plugins/recruit-resources/src/components/Organizations.svelte @@ -14,18 +14,12 @@ -->
-
+
+
@@ -211,16 +219,6 @@
-
@@ -234,19 +232,22 @@ on:change={(e) => (resultQuery = e.detail)} /> -{#if viewlet} - {#if loading} - - {:else} - +{:else if viewlet && viewlet?.$lookup?.descriptor?.component} + - {/if} + }, + totalQuery: {} + }} + /> {/if} diff --git a/plugins/view-resources/src/components/list/List.svelte b/plugins/view-resources/src/components/list/List.svelte index 8c34c8bca5..e400a98123 100644 --- a/plugins/view-resources/src/components/list/List.svelte +++ b/plugins/view-resources/src/components/list/List.svelte @@ -13,7 +13,7 @@ // limitations under the License. -->