Skip to content

Commit 14b5fb2

Browse files
committed
fix(billing): restore lock_timeout after taking the Gmail inbox lock
1 parent cc956c1 commit 14b5fb2

2 files changed

Lines changed: 8 additions & 9 deletions

File tree

‎apps/sim/lib/users/free-allowance.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { userHasGmailAliasAccount } from '@/lib/users/gmail-alias'
66
/**
77
* Whether a new user's identity already had the free allowance: its email or a
88
* linked sign-in (with `includeSignIns`) belonged to a recently deleted account,
9-
* or an earlier account holds its Gmail inbox. Every path that creates a user's
10-
* stats row decides its allowance with this.
9+
* or an earlier account holds its Gmail inbox. Signup, the stats-row fallback,
10+
* and the admin balance grant decide a new row's allowance with this.
1111
*/
1212
export async function identityHadFreeAllowance(
1313
userId: string,

‎apps/sim/lib/users/gmail-alias.ts‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createLogger } from '@sim/logger'
44
import { and, eq, gt, lt, or, sql } from 'drizzle-orm'
55
import { alias } from 'drizzle-orm/pg-core'
66
import { isBillingEnabled } from '@/lib/core/config/env-flags'
7-
import { acquireAdvisoryXactLock } from '@/lib/db/advisory-locks'
7+
import { acquireAdvisoryXactLock, withLockTimeout } from '@/lib/db/advisory-locks'
88
import type { DbOrTx, DbTransaction } from '@/lib/db/types'
99

1010
/**
@@ -45,9 +45,8 @@ function createdRelativeToSubject(compare: typeof lt | typeof gt) {
4545

4646
/**
4747
* Serializes free-allowance decisions for the Gmail inbox this user's address
48-
* delivers to, until `tx` ends. Takes no lock for any other address. Bounds
49-
* `lock_timeout` for the rest of `tx`, so take it in a short transaction of
50-
* its own.
48+
* delivers to, until `tx` ends. Takes no lock for any other address. The wait
49+
* is bounded by its own `lock_timeout`, restored once the lock is held.
5150
*/
5251
export async function acquireGmailInboxLock(tx: DbTransaction, userId: string): Promise<void> {
5352
if (!isBillingEnabled) return
@@ -57,10 +56,10 @@ export async function acquireGmailInboxLock(tx: DbTransaction, userId: string):
5756
.where(eq(user.id, userId))
5857
.limit(1)
5958
if (!row?.mailbox) return
60-
await tx.execute(
61-
sql`select set_config('lock_timeout', ${`${GMAIL_INBOX_LOCK_TIMEOUT_MS}ms`}, true)`
59+
const mailbox = row.mailbox
60+
await withLockTimeout(tx, GMAIL_INBOX_LOCK_TIMEOUT_MS, () =>
61+
acquireAdvisoryXactLock(tx, 'gmail_inbox', `gmail-inbox:${mailbox}`)
6262
)
63-
await acquireAdvisoryXactLock(tx, 'gmail_inbox', `gmail-inbox:${row.mailbox}`)
6463
}
6564

6665
/**

0 commit comments

Comments
 (0)