Skip to content

Commit da8e6ee

Browse files
authored
improvement(db): route additional staleness-tolerant reads to the read replica (#4966)
* improvement(db): route additional staleness-tolerant reads to the read replica * fix(db): keep event-rule and tag-slot reads on the primary * fix(db): keep chunk listing and tag-usage counts on the primary * fix(db): execution-log mention lookup stays on the primary * fix(db): no-activity decision read stays on the primary
1 parent b8daa0f commit da8e6ee

5 files changed

Lines changed: 19 additions & 20 deletions

File tree

apps/sim/app/api/workspaces/[id]/metrics/executions/route.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from '@sim/db'
1+
import { db, dbReplica } from '@sim/db'
22
import { pausedExecutions, permissions, workflow, workflowExecutionLogs } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import { and, eq, gte, inArray, isNotNull, isNull, lte, or, type SQL, sql } from 'drizzle-orm'
@@ -60,7 +60,7 @@ export const GET = withRouteHandler(
6060
wfWhere.push(inArray(workflow.id, wfList))
6161
}
6262

63-
const workflows = await db
63+
const workflows = await dbReplica
6464
.select({ id: workflow.id, name: workflow.name })
6565
.from(workflow)
6666
.where(and(...wfWhere))
@@ -124,7 +124,7 @@ export const GET = withRouteHandler(
124124
}
125125

126126
if (isAllTime) {
127-
const boundsQuery = db
127+
const boundsQuery = dbReplica
128128
.select({
129129
minDate: sql<Date>`MIN(${workflowExecutionLogs.startedAt})`,
130130
maxDate: sql<Date>`MAX(${workflowExecutionLogs.startedAt})`,
@@ -168,7 +168,7 @@ export const GET = withRouteHandler(
168168
lte(workflowExecutionLogs.startedAt, end),
169169
]
170170

171-
const logs = await db
171+
const logs = await dbReplica
172172
.select({
173173
workflowId: workflowExecutionLogs.workflowId,
174174
level: workflowExecutionLogs.level,

apps/sim/lib/copilot/chat/process-contents.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { ChatContext } from '@/stores/panel'
77

88
const { getSkillById } = vi.hoisted(() => ({ getSkillById: vi.fn() }))
99

10-
vi.mock('@sim/db', () => ({ db: {} }))
10+
vi.mock('@sim/db', () => ({ db: {}, dbReplica: {} }))
1111
vi.mock('@sim/db/schema', () => ({ document: {}, knowledgeBase: {} }))
1212
vi.mock('@/lib/workflows/skills/operations', () => ({ getSkillById }))
1313

apps/sim/lib/copilot/chat/process-contents.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from '@sim/db'
1+
import { db, dbReplica } from '@sim/db'
22
import { knowledgeBase } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import {
@@ -454,7 +454,7 @@ async function processKnowledgeFromDb(
454454
if (currentWorkspaceId) {
455455
conditions.push(eq(knowledgeBase.workspaceId, currentWorkspaceId))
456456
}
457-
const kbRows = await db
457+
const kbRows = await dbReplica
458458
.select({
459459
id: knowledgeBase.id,
460460
name: knowledgeBase.name,
@@ -562,7 +562,6 @@ async function processExecutionLogFromDb(
562562
): Promise<AgentContext | null> {
563563
try {
564564
const { workflowExecutionLogs, workflow } = await import('@sim/db/schema')
565-
const { db } = await import('@sim/db')
566565
const rows = await db
567566
.select({
568567
id: workflowExecutionLogs.id,

apps/sim/lib/copilot/chat/workspace-context.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from '@sim/db'
1+
import { dbReplica } from '@sim/db'
22
import {
33
knowledgeBase,
44
knowledgeConnector,
@@ -302,7 +302,7 @@ export async function generateWorkspaceContext(
302302
] = await Promise.all([
303303
getUsersWithPermissions(workspaceId),
304304

305-
db
305+
dbReplica
306306
.select({
307307
id: workflow.id,
308308
name: workflow.name,
@@ -314,7 +314,7 @@ export async function generateWorkspaceContext(
314314
.from(workflow)
315315
.where(and(eq(workflow.workspaceId, workspaceId), isNull(workflow.archivedAt))),
316316

317-
db
317+
dbReplica
318318
.select({
319319
id: workflowFolder.id,
320320
name: workflowFolder.name,
@@ -323,7 +323,7 @@ export async function generateWorkspaceContext(
323323
.from(workflowFolder)
324324
.where(and(eq(workflowFolder.workspaceId, workspaceId), isNull(workflowFolder.archivedAt))),
325325

326-
db
326+
dbReplica
327327
.select({
328328
id: knowledgeBase.id,
329329
name: knowledgeBase.name,
@@ -332,7 +332,7 @@ export async function generateWorkspaceContext(
332332
.from(knowledgeBase)
333333
.where(and(eq(knowledgeBase.workspaceId, workspaceId), isNull(knowledgeBase.deletedAt))),
334334

335-
db
335+
dbReplica
336336
.select({
337337
id: userTableDefinitions.id,
338338
name: userTableDefinitions.name,
@@ -352,7 +352,7 @@ export async function generateWorkspaceContext(
352352

353353
listCustomTools({ userId, workspaceId }),
354354

355-
db
355+
dbReplica
356356
.select({
357357
id: mcpServers.id,
358358
name: mcpServers.name,
@@ -364,7 +364,7 @@ export async function generateWorkspaceContext(
364364

365365
listSkills({ workspaceId, includeBuiltins: false }),
366366

367-
db
367+
dbReplica
368368
.select({
369369
id: workflowSchedule.id,
370370
jobTitle: workflowSchedule.jobTitle,
@@ -388,7 +388,7 @@ export async function generateWorkspaceContext(
388388
tables.length > 0
389389
? await Promise.all(
390390
tables.map(async (t) => {
391-
const [row] = await db
391+
const [row] = await dbReplica
392392
.select({ count: count() })
393393
.from(userTableRows)
394394
.where(eq(userTableRows.tableId, t.id))
@@ -400,7 +400,7 @@ export async function generateWorkspaceContext(
400400
const kbIds = kbs.map((kb) => kb.id)
401401
const connectorRows =
402402
kbIds.length > 0
403-
? await db
403+
? await dbReplica
404404
.select({
405405
knowledgeBaseId: knowledgeConnector.knowledgeBaseId,
406406
connectorType: knowledgeConnector.connectorType,

apps/sim/lib/workspace-events/no-activity.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from '@sim/db'
1+
import { db, dbReplica } from '@sim/db'
22
import { webhook, workflow, workflowDeploymentVersion, workflowExecutionLogs } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import { and, asc, eq, gt, gte, inArray, isNull, ne, or, sql } from 'drizzle-orm'
@@ -42,7 +42,7 @@ export interface NoActivityPollResult {
4242
async function fetchNoActivitySubscriptionPage(
4343
afterWebhookId: string | null
4444
): Promise<SimSubscription[]> {
45-
const rows = await db
45+
const rows = await dbReplica
4646
.select({ webhook, workflow })
4747
.from(webhook)
4848
.innerJoin(workflow, eq(webhook.workflowId, workflow.id))
@@ -105,7 +105,7 @@ async function fetchWatchedWorkflowPage(
105105
conditions.push(gt(workflow.id, afterWorkflowId))
106106
}
107107

108-
return db
108+
return dbReplica
109109
.select({ id: workflow.id, name: workflow.name })
110110
.from(workflow)
111111
.where(and(...conditions))

0 commit comments

Comments
 (0)