mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
improvement(db): reduce connection saturation and egress hotspots (#4594)
* improvement(db): reduce connection saturation and egress hotspots * fix(vfs): preserve native content type in copilot SQL projection * fix(vfs): guard jsonb_array_elements against non-array contentBlocks
This commit is contained in:
@@ -30,7 +30,7 @@ const socketDb = drizzle(
|
||||
prepare: false,
|
||||
idle_timeout: 10,
|
||||
connect_timeout: 20,
|
||||
max: 30,
|
||||
max: 15,
|
||||
onnotice: () => {},
|
||||
}),
|
||||
{ schema }
|
||||
|
||||
@@ -2,7 +2,7 @@ import { db } from '@sim/db'
|
||||
import { mcpServers, workflow, workflowBlocks } from '@sim/db/schema'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import { and, eq, isNull } from 'drizzle-orm'
|
||||
import { and, eq, inArray, isNull } from 'drizzle-orm'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { mcpServerIdParamsSchema } from '@/lib/api/contracts/mcp'
|
||||
import { validationErrorResponse } from '@/lib/api/server'
|
||||
@@ -77,13 +77,11 @@ async function syncToolSchemasToWorkflows(
|
||||
subBlocks: workflowBlocks.subBlocks,
|
||||
})
|
||||
.from(workflowBlocks)
|
||||
.where(eq(workflowBlocks.type, 'agent'))
|
||||
.where(and(eq(workflowBlocks.type, 'agent'), inArray(workflowBlocks.workflowId, workflowIds)))
|
||||
|
||||
const updatedWorkflowIds = new Set<string>()
|
||||
|
||||
for (const block of agentBlocks) {
|
||||
if (!workflowIds.includes(block.workflowId)) continue
|
||||
|
||||
const subBlocks = block.subBlocks as Record<string, unknown> | null
|
||||
if (!subBlocks) continue
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { db } from '@sim/db'
|
||||
import { workflow, workflowBlocks } from '@sim/db/schema'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { and, eq, inArray } from 'drizzle-orm'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
|
||||
import { withMcpAuth } from '@/lib/mcp/middleware'
|
||||
@@ -33,13 +33,13 @@ export const GET = withRouteHandler(
|
||||
const agentBlocks = await db
|
||||
.select({ workflowId: workflowBlocks.workflowId, subBlocks: workflowBlocks.subBlocks })
|
||||
.from(workflowBlocks)
|
||||
.where(eq(workflowBlocks.type, 'agent'))
|
||||
.where(
|
||||
and(eq(workflowBlocks.type, 'agent'), inArray(workflowBlocks.workflowId, workflowIds))
|
||||
)
|
||||
|
||||
const storedTools: StoredMcpTool[] = []
|
||||
|
||||
for (const block of agentBlocks) {
|
||||
if (!workflowMap.has(block.workflowId)) continue
|
||||
|
||||
const subBlocks = block.subBlocks as Record<string, unknown> | null
|
||||
if (!subBlocks) continue
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from '@sim/db/schema'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import { and, desc, eq, isNotNull, isNull, ne } from 'drizzle-orm'
|
||||
import { and, desc, eq, isNotNull, isNull, ne, sql } from 'drizzle-orm'
|
||||
import { listApiKeys } from '@/lib/api-key/service'
|
||||
import { buildWorkspaceMd, type WorkspaceMdData } from '@/lib/copilot/chat/workspace-context'
|
||||
import { extractDocumentStyle } from '@/lib/copilot/vfs/document-style'
|
||||
@@ -1157,7 +1157,27 @@ export class WorkspaceVFS {
|
||||
.select({
|
||||
id: copilotChats.id,
|
||||
title: copilotChats.title,
|
||||
messages: copilotChats.messages,
|
||||
messageCount: sql<number>`COALESCE(jsonb_array_length(${copilotChats.messages}), 0)`,
|
||||
messages: sql<unknown[]>`COALESCE((
|
||||
SELECT jsonb_agg(
|
||||
jsonb_build_object(
|
||||
'role', m->>'role',
|
||||
'content', m->'content',
|
||||
'contentBlocks', COALESCE((
|
||||
SELECT jsonb_agg(jsonb_build_object('type', 'text', 'content', b->'content'))
|
||||
FROM jsonb_array_elements(
|
||||
CASE WHEN jsonb_typeof(m->'contentBlocks') = 'array'
|
||||
THEN m->'contentBlocks'
|
||||
ELSE '[]'::jsonb
|
||||
END
|
||||
) AS b
|
||||
WHERE b->>'type' = 'text'
|
||||
), '[]'::jsonb)
|
||||
)
|
||||
)
|
||||
FROM jsonb_array_elements(${copilotChats.messages}) AS m
|
||||
WHERE m->>'role' IN ('user', 'assistant')
|
||||
), '[]'::jsonb)`,
|
||||
createdAt: copilotChats.createdAt,
|
||||
updatedAt: copilotChats.updatedAt,
|
||||
})
|
||||
@@ -1177,13 +1197,14 @@ export class WorkspaceVFS {
|
||||
const safeName = sanitizeName(title)
|
||||
const prefix = `tasks/${safeName}/`
|
||||
const messages = Array.isArray(task.messages) ? task.messages : []
|
||||
const messageCount = Number(task.messageCount) || 0
|
||||
|
||||
this.files.set(
|
||||
`${prefix}session.md`,
|
||||
serializeTaskSession({
|
||||
id: task.id,
|
||||
title,
|
||||
messageCount: messages.length,
|
||||
messageCount,
|
||||
createdAt: task.createdAt,
|
||||
updatedAt: task.updatedAt,
|
||||
})
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const postgresClient = postgres(connectionString, {
|
||||
prepare: false,
|
||||
idle_timeout: 20,
|
||||
connect_timeout: 30,
|
||||
max: 30,
|
||||
max: 15,
|
||||
onnotice: () => {},
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user