Skip to content

Commit

Permalink
fix: transaction ...: in use: for query (#2278)
Browse files Browse the repository at this point in the history
* fix: transaction ...: in use: for query
- Fixes #2197
- The error is caused by the cache revalidation happening in the background, so we have a racecondition with the other queries we are running in the insertGenericAuditLogs function

* docs: explain for future self

* fix: another racecondition
also bulk insert auditLogs and auditLogTargets

* [autofix.ci] apply automated fixes

---------

Co-authored-by: chronark <dev@chronark.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 11, 2024
1 parent 7064f04 commit 534908e
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions apps/api/src/pkg/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,31 @@ export async function insertGenericAuditLogs(

const { cache, logger, db } = c.get("services");

const auditLogsInserts = [];
const auditLogTargetInserts = [];

for (const log of arr) {
const cacheKey = [log.workspaceId, log.bucket].join(":");
let { val: bucket, err } = await cache.auditLogBucketByWorkspaceIdAndName.swr(
cacheKey,
async () => {
const bucket = await (tx ?? db.primary).query.auditLogBucket.findFirst({
// do not use the transaction here, otherwise we may run into race conditions
// https://github.com/unkeyed/unkey/pull/2278
const bucket = await db.readonly.query.auditLogBucket.findFirst({
where: (table, { eq, and }) =>
and(eq(table.workspaceId, log.workspaceId), eq(table.name, log.bucket)),
});

if (!bucket) {
return undefined;
}

return {
id: bucket.id,
};
},
);

if (err) {
logger.error("Could not find audit log bucket for workspace", {
workspaceId: log.workspaceId,
Expand All @@ -68,7 +76,9 @@ export async function insertGenericAuditLogs(

if (!bucket) {
const bucketId = newId("auditLogBucket");
await (tx ?? db.primary).insert(schema.auditLogBucket).values({
// do not use the transaction here, otherwise we may run into race conditions
// https://github.com/unkeyed/unkey/pull/2278
await db.primary.insert(schema.auditLogBucket).values({
id: bucketId,
workspaceId: log.workspaceId,
name: log.bucket,
Expand All @@ -79,7 +89,7 @@ export async function insertGenericAuditLogs(
}

const auditLogId = newId("auditLog");
await (tx ?? db.primary).insert(schema.auditLog).values({
auditLogsInserts.push({
id: auditLogId,
workspaceId: log.workspaceId,
bucketId: bucket.id,
Expand All @@ -96,8 +106,9 @@ export async function insertGenericAuditLogs(
actorName: log.actor.name,
actorMeta: log.actor.meta,
});
await (tx ?? db.primary).insert(schema.auditLogTarget).values(
log.resources.map((r) => ({

auditLogTargetInserts.push(
...log.resources.map((r) => ({
workspaceId: log.workspaceId,
bucketId: bucket.id,
auditLogId,
Expand All @@ -109,4 +120,8 @@ export async function insertGenericAuditLogs(
})),
);
}

await (tx ?? db.primary).insert(schema.auditLog).values(auditLogsInserts);

await (tx ?? db.primary).insert(schema.auditLogTarget).values(auditLogTargetInserts);
}

0 comments on commit 534908e

Please sign in to comment.