From 4dd9aef5a92a20f9308be03af0f87a000aa43df5 Mon Sep 17 00:00:00 2001 From: Alexander Platov Date: Mon, 26 Aug 2024 14:27:42 +0700 Subject: [PATCH 1/6] Added Table test for Documents (#6356) Signed-off-by: Alexander Platov --- .../tests/documents/documents-content.spec.ts | 143 ++++++++++++++++++ .../sanity/tests/documents/documents.spec.ts | 84 +--------- .../model/documents/document-content-page.ts | 17 +++ tests/sanity/tests/utils.ts | 14 ++ 4 files changed, 175 insertions(+), 83 deletions(-) create mode 100644 tests/sanity/tests/documents/documents-content.spec.ts diff --git a/tests/sanity/tests/documents/documents-content.spec.ts b/tests/sanity/tests/documents/documents-content.spec.ts new file mode 100644 index 0000000000..71271d0e46 --- /dev/null +++ b/tests/sanity/tests/documents/documents-content.spec.ts @@ -0,0 +1,143 @@ +import { test, type Page, expect } from '@playwright/test' +import { + generateId, + getTimeForPlanner, + generateUser, + createAccountAndWorkspace, + createAccount, + getInviteLink, + generateTestData, + getSecondPageByInvite +} from '../utils' +import { NewDocument, NewTeamspace } from '../model/documents/types' +import { LeftSideMenuPage } from '../model/left-side-menu-page' +import { DocumentsPage } from '../model/documents/documents-page' +import { DocumentContentPage } from '../model/documents/document-content-page' +import { PlanningNavigationMenuPage } from '../model/planning/planning-navigation-menu-page' +import { PlanningPage } from '../model/planning/planning-page' +import { SignUpData } from '../model/common-types' +import { TestData } from '../chat/types' + +const retryOptions = { intervals: [1000, 1500, 2500], timeout: 60000 } + +test.describe('Content in the Documents tests', () => { + let testData: TestData + let newUser2: SignUpData + let testTeamspace: NewTeamspace + let testDocument: NewDocument + + let leftSideMenuPage: LeftSideMenuPage + let documentsPage: DocumentsPage + let documentContentPage: DocumentContentPage + + let secondPage: Page + let leftSideMenuSecondPage: LeftSideMenuPage + let documentsSecondPage: DocumentsPage + let documentContentSecondPage: DocumentContentPage + + test.beforeEach(async ({ browser, page, request }) => { + leftSideMenuPage = new LeftSideMenuPage(page) + documentsPage = new DocumentsPage(page) + documentContentPage = new DocumentContentPage(page) + testTeamspace = { + title: `Teamspace-${generateId()}`, + description: 'Teamspace description', + autoJoin: true + } + testDocument = { + title: `Document-${generateId()}`, + space: testTeamspace.title + } + + testData = generateTestData() + newUser2 = generateUser() + await createAccountAndWorkspace(page, request, testData) + await createAccount(request, newUser2) + + const linkText = await getInviteLink(page) + await leftSideMenuPage.clickDocuments() + await documentsPage.checkTeamspaceNotExist(testTeamspace.title) + await documentsPage.createNewTeamspace(testTeamspace) + secondPage = await getSecondPageByInvite(browser, linkText, newUser2) + + leftSideMenuSecondPage = new LeftSideMenuPage(secondPage) + documentsSecondPage = new DocumentsPage(secondPage) + documentContentSecondPage = new DocumentContentPage(secondPage) + await documentsPage.clickOnButtonCreateDocument() + await documentsPage.createDocument(testDocument) + await documentsPage.openDocument(testDocument.title) + await documentContentPage.checkDocumentTitle(testDocument.title) + }) + + test('ToDos in the Document', async () => { + const contents: string[] = ['work', 'meet up'] + let content: string = '' + + for (let i = 0; i < contents.length; i++) { + content = await documentContentPage.addContentToTheNewLine(`${i === 0 ? '[] ' : ''}${contents[i]}`) + await documentContentPage.checkContent(content) + } + for (const line of contents) { + await documentContentPage.assignToDo(`${newUser2.lastName} ${newUser2.firstName}`, line) + } + + await leftSideMenuSecondPage.clickDocuments() + await documentsSecondPage.openTeamspace(testDocument.space) + await documentsSecondPage.openDocument(testDocument.title) + await documentContentSecondPage.checkDocumentTitle(testDocument.title) + await documentContentSecondPage.checkContent(content) + await leftSideMenuSecondPage.clickPlanner() + + const planningNavigationMenuPage = new PlanningNavigationMenuPage(secondPage) + await planningNavigationMenuPage.clickOnButtonToDoAll() + const planningPage = new PlanningPage(secondPage) + const time: string = getTimeForPlanner() + await planningPage.dragToCalendar(contents[0], 1, time) + await planningPage.dragToCalendar(contents[1], 1, time, true) + await planningPage.checkInSchedule(contents[0]) + await planningPage.checkInSchedule(contents[1]) + await planningPage.markDoneInToDos(contents[0]) + await planningPage.markDoneInToDos(contents[1]) + await secondPage.close() + + for (const line of contents) await documentContentPage.checkToDo(line, true) + }) + + test('Table in the Document', async ({ page }) => { + await documentContentPage.inputContentParapraph().click() + await documentContentPage.leftMenu().click() + await documentContentPage.menuPopupItemButton('Table').click() + await documentContentPage.menuPopupItemButton('1x2').first().click() + await documentContentPage.proseTableCell(0, 0).fill('One') + await documentContentPage.proseTableCell(0, 1).fill('Two') + await documentContentPage.buttonInsertColumn().click() + await documentContentPage.proseTableCell(0, 1).fill('Three') + + await documentContentPage.proseTableColumnHandle(1).hover() + await expect(async () => { + await page.mouse.down() + const boundingBox = await documentContentPage.proseTableCell(0, 1).boundingBox() + expect(boundingBox).toBeTruthy() + if (boundingBox != null) { + await page.mouse.move(boundingBox.x + boundingBox.width * 2, boundingBox.y - 5) + await page.mouse.move(boundingBox.x + boundingBox.width * 2 + 5, boundingBox.y - 5) + await page.mouse.up() + } + }).toPass(retryOptions) + + await documentContentPage.buttonInsertLastRow().click() + await documentContentPage.proseTableCell(1, 1).fill('Bottom') + await documentContentPage.buttonInsertInnerRow().click() + await documentContentPage.proseTableCell(1, 1).fill('Middle') + + await leftSideMenuSecondPage.clickDocuments() + await documentsSecondPage.openTeamspace(testDocument.space) + await documentsSecondPage.openDocument(testDocument.title) + await documentContentSecondPage.checkDocumentTitle(testDocument.title) + await expect(documentContentSecondPage.proseTableCell(1, 1)).toContainText('Middle') + await documentContentSecondPage.proseTableCell(1, 1).dblclick() + await documentContentSecondPage.proseTableCell(1, 1).fill('Center') + await expect(documentContentPage.proseTableCell(1, 1)).toContainText('Center', { timeout: 5000 }) + await secondPage.close() + }) +}) diff --git a/tests/sanity/tests/documents/documents.spec.ts b/tests/sanity/tests/documents/documents.spec.ts index e89891a961..50b8acdf5d 100644 --- a/tests/sanity/tests/documents/documents.spec.ts +++ b/tests/sanity/tests/documents/documents.spec.ts @@ -1,26 +1,9 @@ import { test } from '@playwright/test' -import { - generateId, - getSecondPage, - PlatformSetting, - PlatformURI, - getTimeForPlanner, - generateUser, - createAccountAndWorkspace, - createAccount, - getInviteLink, - generateTestData, - reLogin -} from '../utils' +import { generateId, getSecondPage, PlatformSetting, PlatformURI } from '../utils' import { NewDocument, NewTeamspace } from '../model/documents/types' import { LeftSideMenuPage } from '../model/left-side-menu-page' import { DocumentsPage } from '../model/documents/documents-page' import { DocumentContentPage } from '../model/documents/document-content-page' -import { PlanningNavigationMenuPage } from '../model/planning/planning-navigation-menu-page' -import { PlanningPage } from '../model/planning/planning-page' -import { SignUpData } from '../model/common-types' -import { SignInJoinPage } from '../model/signin-page' -import { TestData } from '../chat/types' test.use({ storageState: PlatformSetting @@ -186,69 +169,4 @@ test.describe('Documents tests', () => { await documentContentPage.checkDocumentTitle(newDocument.title) await documentContentPage.checkDocumentLocked() }) - - test('ToDos in the Document', async ({ page, browser, request }) => { - const testData: TestData = generateTestData() - await createAccountAndWorkspace(page, request, testData) - const newUser2: SignUpData = generateUser() - await createAccount(request, newUser2) - - const todosTeamspace: NewTeamspace = { - title: `ToDos Teamspace-${generateId()}`, - description: 'ToDos Teamspace description', - autoJoin: true - } - const todosDocument: NewDocument = { - title: `ToDos in the Document-${generateId()}`, - space: todosTeamspace.title - } - const contents: string[] = ['work', 'meet up'] - let content: string = '' - - const linkText = await getInviteLink(page) - await leftSideMenuPage.clickDocuments() - await documentsPage.checkTeamspaceNotExist(todosTeamspace.title) - await documentsPage.createNewTeamspace(todosTeamspace) - const page2 = await browser.newPage() - await page2.goto(linkText ?? '') - const joinPage: SignInJoinPage = new SignInJoinPage(page2) - await joinPage.join(newUser2) - await page2.goto(`${PlatformURI}/workbench/sanity-ws`) - - await documentsPage.clickOnButtonCreateDocument() - await documentsPage.createDocument(todosDocument) - await documentsPage.openDocument(todosDocument.title) - await documentContentPage.checkDocumentTitle(todosDocument.title) - for (let i = 0; i < contents.length; i++) { - content = await documentContentPage.addContentToTheNewLine(`${i === 0 ? '[] ' : ''}${contents[i]}`) - await documentContentPage.checkContent(content) - } - for (const line of contents) { - await documentContentPage.assignToDo(`${newUser2.lastName} ${newUser2.firstName}`, line) - } - - await reLogin(page2, { ...testData, userName: newUser2.email }) - const leftSideMenuPageSecond = new LeftSideMenuPage(page2) - await leftSideMenuPageSecond.clickDocuments() - const documentsPageSecond = new DocumentsPage(page2) - await documentsPageSecond.openTeamspace(todosDocument.space) - await documentsPageSecond.openDocument(todosDocument.title) - const documentContentPageSecond = new DocumentContentPage(page2) - await documentContentPageSecond.checkDocumentTitle(todosDocument.title) - await documentContentPageSecond.checkContent(content) - await leftSideMenuPageSecond.clickPlanner() - - const planningNavigationMenuPage = new PlanningNavigationMenuPage(page2) - await planningNavigationMenuPage.clickOnButtonToDoAll() - const planningPage = new PlanningPage(page2) - const time: string = getTimeForPlanner() - await planningPage.dragToCalendar(contents[0], 1, time) - await planningPage.dragToCalendar(contents[1], 1, time, true) - await planningPage.checkInSchedule(contents[0]) - await planningPage.checkInSchedule(contents[1]) - await planningPage.markDoneInToDos(contents[0]) - await planningPage.markDoneInToDos(contents[1]) - for (const line of contents) await documentContentPage.checkToDo(line, true) - await page2.close() - }) }) diff --git a/tests/sanity/tests/model/documents/document-content-page.ts b/tests/sanity/tests/model/documents/document-content-page.ts index 30f1532d79..b18660fc43 100644 --- a/tests/sanity/tests/model/documents/document-content-page.ts +++ b/tests/sanity/tests/model/documents/document-content-page.ts @@ -11,6 +11,23 @@ export class DocumentContentPage extends CommonPage { readonly buttonDocumentTitle = (): Locator => this.page.locator('div[class*="main-content"] div.title input') readonly inputContent = (): Locator => this.page.locator('div.textInput div.tiptap') + readonly inputContentParapraph = (): Locator => this.page.locator('div.textInput div.tiptap > p') + readonly leftMenu = (): Locator => this.page.locator('div.tiptap-left-menu') + readonly proseTableCell = (row: number, col: number): Locator => + this.page.locator('table.proseTable').locator('tr').nth(row).locator('td').nth(col).locator('p') + + readonly proseTableColumnHandle = (col: number): Locator => + this.page.locator('table.proseTable').locator('tr').first().locator('td').nth(col).locator('div.table-col-handle') + + readonly buttonInsertColumn = (col: number = 0): Locator => + this.page.locator('div.table-col-insert').nth(col).locator('button') + + readonly buttonInsertLastRow = (): Locator => + this.page.locator('table.proseTable + div.table-button-container__col + div.table-button-container__row') + + readonly buttonInsertInnerRow = (row: number = 0): Locator => + this.page.locator('table.proseTable').locator('tr').nth(row).locator('div.table-row-insert button') + readonly buttonToolbarLink = (): Locator => this.page.locator('div.text-editor-toolbar button[data-id="btnLink"]') readonly inputFormLink = (): Locator => this.page.locator('form[id="text-editor:string:Link"] input') readonly buttonFormLinkSave = (): Locator => diff --git a/tests/sanity/tests/utils.ts b/tests/sanity/tests/utils.ts index 2b9ca31700..03d598f381 100644 --- a/tests/sanity/tests/utils.ts +++ b/tests/sanity/tests/utils.ts @@ -8,6 +8,7 @@ import { SignUpData } from './model/common-types' import { ApiEndpoint } from './API/Api' import { SelectWorkspacePage } from './model/select-workspace-page' import { LoginPage } from './model/login-page' +import { SignInJoinPage } from './model/signin-page' export const PlatformURI = process.env.PLATFORM_URI as string export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string @@ -109,6 +110,19 @@ export async function getSecondPage (browser: Browser): Promise<{ page: Page, co const userSecondContext = await browser.newContext({ storageState: PlatformSettingSecond }) return { page: await userSecondContext.newPage(), context: userSecondContext } } + +export async function getSecondPageByInvite ( + browser: Browser, + linkText: string | null, + newUser: SignUpData +): Promise { + const page = await browser.newPage() + await page.goto(linkText ?? '') + const joinPage: SignInJoinPage = new SignInJoinPage(page) + await joinPage.join(newUser) + return page +} + export function expectToContainsOrdered (val: Locator, text: string[], timeout?: number): Promise { const origIssuesExp = new RegExp('.*' + text.join('.*') + '.*') return expect(val).toHaveText(origIssuesExp, { timeout }) From eaa23c771da171af648c95729de536510f27cfd5 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Mon, 26 Aug 2024 23:15:56 +0700 Subject: [PATCH 2/6] Docker compose for more easy local debug (#6348) Signed-off-by: Andrey Sobolev --- dev/.env | 3 ++- dev/docker-compose.yaml | 49 ++++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/dev/.env b/dev/.env index 90fe452486..8306222d28 100644 --- a/dev/.env +++ b/dev/.env @@ -1 +1,2 @@ -STORAGE_CONFIG="minio|minio?accessKey=minioadmin&secretKey=minioadmin" \ No newline at end of file +STORAGE_CONFIG="minio|minio?accessKey=minioadmin&secretKey=minioadmin" +MONGO_URL=mongodb://mongodb:27017?compressors=snappy \ No newline at end of file diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index e7e9d000ac..2debbc9482 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -2,6 +2,15 @@ services: mongodb: image: 'mongo:7-jammy' container_name: mongodb + extra_hosts: + - "host.docker.internal:host-gateway" + healthcheck: + test: echo "try { db.currentOp().ok } catch (err) { }" | mongosh --port 27017 --quiet + interval: 5s + timeout: 30s + start_period: 0s + start_interval: 1s + retries: 30 environment: - PUID=1000 - PGID=1000 @@ -52,11 +61,11 @@ services: environment: - ACCOUNT_PORT=3000 - SERVER_SECRET=secret - - MONGO_URL=mongodb://mongodb:27017?compressors=snappy - - TRANSACTOR_URL=ws://transactor:3333;ws://localhost:3333 + - MONGO_URL=${MONGO_URL} + - TRANSACTOR_URL=ws://host.docker.internal:3333;ws://localhost:3333 - SES_URL= - STORAGE_CONFIG=${STORAGE_CONFIG} - - FRONT_URL=http://localhost:8087 + - FRONT_URL=http://host.docker.internal:8087 - RESERVED_DB_NAMES=telegram,gmail,github - MODEL_ENABLED=* - LAST_NAME_FIRST=true @@ -76,8 +85,8 @@ services: environment: - COLLABORATOR_PORT=3078 - SECRET=secret - - ACCOUNTS_URL=http://account:3000 - - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - ACCOUNTS_URL=http://host.docker.internal:3000 + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName":"collaborator","maxPoolSize":2}' - STORAGE_CONFIG=${STORAGE_CONFIG} restart: unless-stopped @@ -96,11 +105,11 @@ services: - UV_THREADPOOL_SIZE=10 - SERVER_PORT=8080 - SERVER_SECRET=secret - - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName":"front","maxPoolSize":1}' - ACCOUNTS_URL=http://localhost:3000 - UPLOAD_URL=/files - - ELASTIC_URL=http://elastic:9200 + - ELASTIC_URL=http://host.docker.internal:9200 - GMAIL_URL=http://localhost:8088 - CALENDAR_URL=http://localhost:8095 - TELEGRAM_URL=http://localhost:8086 @@ -135,17 +144,17 @@ services: - SERVER_PORT=3333 - SERVER_SECRET=secret - ENABLE_COMPRESSION=true - - ELASTIC_URL=http://elastic:9200 - - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - ELASTIC_URL=http://host.docker.internal:9200 + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName": "transactor", "maxPoolSize": 10}' - METRICS_CONSOLE=false - METRICS_FILE=metrics.txt - STORAGE_CONFIG=${STORAGE_CONFIG} - - REKONI_URL=http://rekoni:4004 + - REKONI_URL=http://host.docker.internal:4004 - FRONT_URL=http://localhost:8087 # - APM_SERVER_URL=http://apm-server:8200 - SES_URL='' - - ACCOUNTS_URL=http://account:3000 + - ACCOUNTS_URL=http://host.docker.internal:3000 - LAST_NAME_FIRST=true - ELASTIC_INDEX_NAME=local_storage_index - BRANDING_PATH=/var/cfg/branding.json @@ -166,7 +175,7 @@ services: - 4005:4005 environment: - SECRET=secret - - MONGO_URL=mongodb://mongodb:27017?compressors=snappy + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName":"print","maxPoolSize":1}' - STORAGE_CONFIG=${STORAGE_CONFIG} deploy: @@ -183,11 +192,11 @@ services: - ../services/sign/pod-sign/debug/branding.json:/var/cfg/branding.json environment: - SECRET=secret - - MONGO_URL=mongodb://mongodb:27017 + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName":"sign","maxPoolSize":1}' - MINIO_ENDPOINT=minio - MINIO_ACCESS_KEY=minioadmin - - ACCOUNTS_URL=http://account:3000 + - ACCOUNTS_URL=http://host.docker.internal:3000 - MINIO_SECRET_KEY=minioadmin - CERTIFICATE_PATH=/var/cfg/certificate.p12 - SERVICE_ID=sign-service @@ -204,10 +213,10 @@ services: environment: - SECRET=secret - PORT=4007 - - MONGO_URL=mongodb://mongodb:27017 + - MONGO_URL=${MONGO_URL} - 'MONGO_OPTIONS={"appName":"analytics","maxPoolSize":1}' - SERVICE_ID=analytics-collector-service - - ACCOUNTS_URL=http://account:3000 + - ACCOUNTS_URL=http://host.docker.internal:3000 - SUPPORT_WORKSPACE=support deploy: resources: @@ -218,8 +227,8 @@ services: restart: unless-stopped environment: - SERVER_SECRET=secret - - MONGO_URL=mongodb://mongodb:27017 - - ACCOUNTS_URL=http://account:3000 + - MONGO_URL=${MONGO_URL} + - ACCOUNTS_URL=http://host.docker.internal:3000 - SUPPORT_WORKSPACE=support - FIRST_NAME=Jolie - LAST_NAME=AI @@ -236,11 +245,11 @@ services: # environment: # - PORT=4020 # - BOT_TOKEN=token -# - MONGO_URL=mongodb://mongodb:27017 +# - MONGO_URL=${MONGO_URL} # - MONGO_DB=telegram-bot # - SECRET=secret # - DOMAIN=domain -# - ACCOUNTS_URL=http://account:3000 +# - ACCOUNTS_URL=http://host.docker.internal:3000 # - SERVICE_ID=telegram-bot-service # deploy: # resources: From e231f89e0b7d5baa8b6fc5fc10192252d95ab16d Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Tue, 27 Aug 2024 12:28:27 +0700 Subject: [PATCH 3/6] UBERF-7946: Remove bulk in mongo adapter (#6395) Signed-off-by: Andrey Sobolev --- server/mongo/src/storage.ts | 122 +++++++++++++----------------------- 1 file changed, 45 insertions(+), 77 deletions(-) diff --git a/server/mongo/src/storage.ts b/server/mongo/src/storage.ts index 051af5249c..4644eda2fb 100644 --- a/server/mongo/src/storage.ts +++ b/server/mongo/src/storage.ts @@ -75,7 +75,6 @@ import { createHash } from 'crypto' import { type AbstractCursor, type AnyBulkWriteOperation, - type BulkWriteResult, type Collection, type Db, type Document, @@ -1107,57 +1106,6 @@ class MongoAdapter extends MongoAdapterBase { } } - bulkOps = new Map[]>() - - async _pushBulk (ctx: MeasureContext): Promise { - const bulk = Array.from(this.bulkOps.entries()) - this.bulkOps.clear() - if (bulk.length === 0) { - return - } - const promises: Promise[] = [] - for (const [domain, ops] of bulk) { - if (ops === undefined || ops.length === 0) { - continue - } - const coll = this.db.collection(domain) - - promises.push( - addOperation( - ctx, - 'bulk-write', - { domain, operations: ops.length }, - async (ctx) => - await ctx.with( - 'bulk-write', - { domain }, - () => - coll.bulkWrite(ops, { - ordered: false - }), - { - domain, - operations: ops.length - } - ) - ) - ) - } - await Promise.all(promises) - } - - async pushBulk (ctx: MeasureContext, domain: Domain, ops: AnyBulkWriteOperation[]): Promise { - const existing = this.bulkOps.get(domain) - if (existing !== undefined) { - existing.push(...ops) - } else { - this.bulkOps.set(domain, ops) - } - // We need to wait next cycle to send request - await new Promise((resolve) => setImmediate(resolve)) - await this._pushBulk(ctx) - } - async tx (ctx: MeasureContext, ...txes: Tx[]): Promise { const result: TxResult[] = [] @@ -1171,6 +1119,7 @@ class MongoAdapter extends MongoAdapterBase { const stTime = Date.now() const st = Date.now() + let promises: Promise[] = [] for (const [domain, txs] of byDomain) { if (domain === undefined) { continue @@ -1227,9 +1176,37 @@ class MongoAdapter extends MongoAdapterBase { } if (ops.length > 0) { - await this.pushBulk(ctx, domain, ops) + if (ops === undefined || ops.length === 0) { + continue + } + const coll = this.db.collection(domain) + + promises.push( + addOperation( + ctx, + 'bulk-write', + { domain, operations: ops.length }, + async (ctx) => + await ctx.with( + 'bulk-write', + { domain }, + () => + coll.bulkWrite(ops, { + ordered: false + }), + { + domain, + operations: ops.length + } + ) + ) + ) } if (domainBulk.findUpdate.size > 0) { + if (promises.length > 0) { + await Promise.all(promises) + promises = [] + } const coll = this.db.collection(domain) await ctx.with( @@ -1255,6 +1232,10 @@ class MongoAdapter extends MongoAdapterBase { } if (domainBulk.raw.length > 0) { + if (promises.length > 0) { + await Promise.all(promises) + promises = [] + } await ctx.with( 'raw', {}, @@ -1270,6 +1251,9 @@ class MongoAdapter extends MongoAdapterBase { ) } } + if (promises.length > 0) { + await Promise.all(promises) + } return result } @@ -1511,17 +1495,12 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter { await this._db.init(DOMAIN_TX) } - txBulk: Tx[] = [] - - async _bulkTx (ctx: MeasureContext): Promise { - const txes = this.txBulk - this.txBulk = [] - - if (txes.length === 0) { - return + override async tx (ctx: MeasureContext, ...tx: Tx[]): Promise { + if (tx.length === 0) { + return [] } - const opName = txes.length === 1 ? 'tx-one' : 'tx' + const opName = tx.length === 1 ? 'tx-one' : 'tx' await addOperation( ctx, opName, @@ -1532,31 +1511,20 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter { { domain: 'tx' }, () => this.txCollection().insertMany( - txes.map((it) => translateDoc(it)), + tx.map((it) => translateDoc(it)), { ordered: false } ), { - count: txes.length + count: tx.length } ), - { domain: 'tx', count: txes.length } + { domain: 'tx', count: tx.length } ) ctx.withSync('handleEvent', {}, () => { - this.handleEvent(DOMAIN_TX, 'add', txes.length) + this.handleEvent(DOMAIN_TX, 'add', tx.length) }) - } - - override async tx (ctx: MeasureContext, ...tx: Tx[]): Promise { - if (tx.length === 0) { - return [] - } - this.txBulk.push(...tx) - - // We need to wait next cycle to send request - await new Promise((resolve) => setImmediate(resolve)) - await this._bulkTx(ctx) return [] } From d7820206c014fd369caed153cab60956aafad485 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Tue, 27 Aug 2024 14:10:50 +0700 Subject: [PATCH 4/6] UBERF-7944: Support for not_planed close for issues (#6396) Signed-off-by: Andrey Sobolev --- .../presenters/GithubReviewPresenter.svelte | 17 ++--- .../GithubReviewThreadPresenter.svelte | 6 +- .../github/pod-github/src/sync/issueBase.ts | 7 +- services/github/pod-github/src/sync/issues.ts | 70 ++++++++++++++++--- .../pod-github/src/sync/pullrequests.ts | 2 +- .../pod-github/src/sync/reviewThreads.ts | 10 +-- 6 files changed, 81 insertions(+), 31 deletions(-) diff --git a/services/github/github-resources/src/components/presenters/GithubReviewPresenter.svelte b/services/github/github-resources/src/components/presenters/GithubReviewPresenter.svelte index b06a6803eb..dcdb57ff49 100644 --- a/services/github/github-resources/src/components/presenters/GithubReviewPresenter.svelte +++ b/services/github/github-resources/src/components/presenters/GithubReviewPresenter.svelte @@ -3,24 +3,17 @@ // -->