From bad7757a62e1845a2820eab50b54ae9cace251f1 Mon Sep 17 00:00:00 2001 From: bkellam Date: Wed, 29 Oct 2025 23:42:53 -0700 Subject: [PATCH] remove transaction for job creation --- .../backend/src/ee/repoPermissionSyncer.ts | 35 +++++++++--------- .../backend/src/ee/userPermissionSyncer.ts | 37 ++++++++++--------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/packages/backend/src/ee/repoPermissionSyncer.ts b/packages/backend/src/ee/repoPermissionSyncer.ts index 683e3659..a28e68b1 100644 --- a/packages/backend/src/ee/repoPermissionSyncer.ts +++ b/packages/backend/src/ee/repoPermissionSyncer.ts @@ -110,24 +110,25 @@ export class RepoPermissionSyncer { } private async schedulePermissionSync(repos: Repo[]) { - await this.db.$transaction(async (tx) => { - const jobs = await tx.repoPermissionSyncJob.createManyAndReturn({ - data: repos.map(repo => ({ - repoId: repo.id, - })), - }); - - await this.queue.addBulk(jobs.map((job) => ({ - name: 'repoPermissionSyncJob', - data: { - jobId: job.id, - }, - opts: { - removeOnComplete: env.REDIS_REMOVE_ON_COMPLETE, - removeOnFail: env.REDIS_REMOVE_ON_FAIL, - } - }))) + // @note: we don't perform this in a transaction because + // we want to avoid the situation where a job is created and run + // prior to the transaction being committed. + const jobs = await this.db.repoPermissionSyncJob.createManyAndReturn({ + data: repos.map(repo => ({ + repoId: repo.id, + })), }); + + await this.queue.addBulk(jobs.map((job) => ({ + name: 'repoPermissionSyncJob', + data: { + jobId: job.id, + }, + opts: { + removeOnComplete: env.REDIS_REMOVE_ON_COMPLETE, + removeOnFail: env.REDIS_REMOVE_ON_FAIL, + } + }))) } private async runJob(job: Job) { diff --git a/packages/backend/src/ee/userPermissionSyncer.ts b/packages/backend/src/ee/userPermissionSyncer.ts index 326ea91c..f3069eaf 100644 --- a/packages/backend/src/ee/userPermissionSyncer.ts +++ b/packages/backend/src/ee/userPermissionSyncer.ts @@ -6,7 +6,7 @@ import { Redis } from "ioredis"; import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "../constants.js"; import { env } from "../env.js"; import { createOctokitFromToken, getReposForAuthenticatedUser } from "../github.js"; -import { createGitLabFromOAuthToken, createGitLabFromPersonalAccessToken, getProjectsForAuthenticatedUser } from "../gitlab.js"; +import { createGitLabFromOAuthToken, getProjectsForAuthenticatedUser } from "../gitlab.js"; import { hasEntitlement } from "@sourcebot/shared"; import { Settings } from "../types.js"; @@ -113,24 +113,25 @@ export class UserPermissionSyncer { } private async schedulePermissionSync(users: User[]) { - await this.db.$transaction(async (tx) => { - const jobs = await tx.userPermissionSyncJob.createManyAndReturn({ - data: users.map(user => ({ - userId: user.id, - })), - }); - - await this.queue.addBulk(jobs.map((job) => ({ - name: 'userPermissionSyncJob', - data: { - jobId: job.id, - }, - opts: { - removeOnComplete: env.REDIS_REMOVE_ON_COMPLETE, - removeOnFail: env.REDIS_REMOVE_ON_FAIL, - } - }))) + // @note: we don't perform this in a transaction because + // we want to avoid the situation where a job is created and run + // prior to the transaction being committed. + const jobs = await this.db.userPermissionSyncJob.createManyAndReturn({ + data: users.map(user => ({ + userId: user.id, + })), }); + + await this.queue.addBulk(jobs.map((job) => ({ + name: 'userPermissionSyncJob', + data: { + jobId: job.id, + }, + opts: { + removeOnComplete: env.REDIS_REMOVE_ON_COMPLETE, + removeOnFail: env.REDIS_REMOVE_ON_FAIL, + } + }))) } private async runJob(job: Job) {