diff --git a/ui/src/app/api/jobs/[jobID]/delete/route.ts b/ui/src/app/api/jobs/[jobID]/delete/route.ts index e2d3a0c..8fa2422 100644 --- a/ui/src/app/api/jobs/[jobID]/delete/route.ts +++ b/ui/src/app/api/jobs/[jobID]/delete/route.ts @@ -1,11 +1,9 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import { getTrainingFolder } from '@/server/settings'; import path from 'path'; import fs from 'fs'; -const prisma = new PrismaClient(); - export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/files/route.ts b/ui/src/app/api/jobs/[jobID]/files/route.ts index c0642d7..b8fc1c8 100644 --- a/ui/src/app/api/jobs/[jobID]/files/route.ts +++ b/ui/src/app/api/jobs/[jobID]/files/route.ts @@ -1,11 +1,9 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import path from 'path'; import fs from 'fs'; import { getTrainingFolder } from '@/server/settings'; -const prisma = new PrismaClient(); - export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/log/route.ts b/ui/src/app/api/jobs/[jobID]/log/route.ts index c353166..731a546 100644 --- a/ui/src/app/api/jobs/[jobID]/log/route.ts +++ b/ui/src/app/api/jobs/[jobID]/log/route.ts @@ -1,12 +1,10 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import path from 'path'; import fs from 'fs'; import type { FileHandle } from 'fs/promises'; import { getTrainingFolder } from '@/server/settings'; -const prisma = new PrismaClient(); - export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/loss/route.ts b/ui/src/app/api/jobs/[jobID]/loss/route.ts index e6437a2..89ac0df 100644 --- a/ui/src/app/api/jobs/[jobID]/loss/route.ts +++ b/ui/src/app/api/jobs/[jobID]/loss/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import path from 'path'; import fs from 'fs'; import { getTrainingFolder } from '@/server/settings'; @@ -8,8 +8,6 @@ import sqlite3 from 'sqlite3'; export const runtime = 'nodejs'; -const prisma = new PrismaClient(); - function openDb(filename: string) { const db = new sqlite3.Database(filename); db.configure('busyTimeout', 30_000); diff --git a/ui/src/app/api/jobs/[jobID]/mark_stopped/route.ts b/ui/src/app/api/jobs/[jobID]/mark_stopped/route.ts index 39cd353..2b38cc6 100644 --- a/ui/src/app/api/jobs/[jobID]/mark_stopped/route.ts +++ b/ui/src/app/api/jobs/[jobID]/mark_stopped/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/plugin/route.ts b/ui/src/app/api/jobs/[jobID]/plugin/route.ts index cadcf00..946ea2f 100644 --- a/ui/src/app/api/jobs/[jobID]/plugin/route.ts +++ b/ui/src/app/api/jobs/[jobID]/plugin/route.ts @@ -1,11 +1,9 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import path from 'path'; import fs from 'fs'; import { getTrainingFolder } from '@/server/settings'; -const prisma = new PrismaClient(); - export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/sample_now/route.ts b/ui/src/app/api/jobs/[jobID]/sample_now/route.ts index 7d785be..37ef136 100644 --- a/ui/src/app/api/jobs/[jobID]/sample_now/route.ts +++ b/ui/src/app/api/jobs/[jobID]/sample_now/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/samples/route.ts b/ui/src/app/api/jobs/[jobID]/samples/route.ts index d5f9bd8..6a2aafe 100644 --- a/ui/src/app/api/jobs/[jobID]/samples/route.ts +++ b/ui/src/app/api/jobs/[jobID]/samples/route.ts @@ -1,11 +1,9 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import path from 'path'; import fs from 'fs'; import { getTrainingFolder } from '@/server/settings'; -const prisma = new PrismaClient(); - export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/save_now/route.ts b/ui/src/app/api/jobs/[jobID]/save_now/route.ts index 0a6e54b..6addbe6 100644 --- a/ui/src/app/api/jobs/[jobID]/save_now/route.ts +++ b/ui/src/app/api/jobs/[jobID]/save_now/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/start/route.ts b/ui/src/app/api/jobs/[jobID]/start/route.ts index 0417dcf..34cb9ce 100644 --- a/ui/src/app/api/jobs/[jobID]/start/route.ts +++ b/ui/src/app/api/jobs/[jobID]/start/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { const { jobID } = await params; diff --git a/ui/src/app/api/jobs/[jobID]/stop/route.ts b/ui/src/app/api/jobs/[jobID]/stop/route.ts index 8b49f53..cb14ad6 100644 --- a/ui/src/app/api/jobs/[jobID]/stop/route.ts +++ b/ui/src/app/api/jobs/[jobID]/stop/route.ts @@ -1,10 +1,9 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); -const prisma = new PrismaClient(); const isWindows = process.platform === 'win32'; export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) { diff --git a/ui/src/app/api/jobs/route.ts b/ui/src/app/api/jobs/route.ts index 2077846..b953069 100644 --- a/ui/src/app/api/jobs/route.ts +++ b/ui/src/app/api/jobs/route.ts @@ -1,10 +1,8 @@ import { NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import { isMac } from '@/helpers/basic'; import { cached } from '@/server/apiCache'; -const prisma = new PrismaClient(); - export async function GET(request: Request) { const { searchParams } = new URL(request.url); const id = searchParams.get('id'); diff --git a/ui/src/app/api/queue/[queueID]/start/route.ts b/ui/src/app/api/queue/[queueID]/start/route.ts index d67ff4e..3bc6791 100644 --- a/ui/src/app/api/queue/[queueID]/start/route.ts +++ b/ui/src/app/api/queue/[queueID]/start/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { queueID: string } }) { const { queueID } = await params; diff --git a/ui/src/app/api/queue/[queueID]/stop/route.ts b/ui/src/app/api/queue/[queueID]/stop/route.ts index 87e608b..03f9b37 100644 --- a/ui/src/app/api/queue/[queueID]/stop/route.ts +++ b/ui/src/app/api/queue/[queueID]/stop/route.ts @@ -1,7 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: NextRequest, { params }: { params: { queueID: string } }) { const { queueID } = await params; diff --git a/ui/src/app/api/queue/route.ts b/ui/src/app/api/queue/route.ts index 08c6d4b..eb1eb86 100644 --- a/ui/src/app/api/queue/route.ts +++ b/ui/src/app/api/queue/route.ts @@ -1,7 +1,5 @@ import { NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; - -const prisma = new PrismaClient(); +import prisma from '@/server/prisma'; export async function GET(request: Request) { const { searchParams } = new URL(request.url); diff --git a/ui/src/app/api/settings/route.ts b/ui/src/app/api/settings/route.ts index 62528cd..24722a2 100644 --- a/ui/src/app/api/settings/route.ts +++ b/ui/src/app/api/settings/route.ts @@ -1,10 +1,8 @@ import { NextResponse } from 'next/server'; -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import { defaultTrainFolder, defaultDatasetsFolder } from '@/paths'; import { flushCache } from '@/server/settings'; -const prisma = new PrismaClient(); - export async function GET() { try { const settings = await prisma.settings.findMany(); diff --git a/ui/src/server/prisma.ts b/ui/src/server/prisma.ts new file mode 100644 index 0000000..b6b536e --- /dev/null +++ b/ui/src/server/prisma.ts @@ -0,0 +1,16 @@ +import { PrismaClient } from '@prisma/client'; + +// Single shared PrismaClient for the whole server. Route files must import +// this instead of constructing their own client — each PrismaClient spawns +// its own query engine + connection pool, and a pile of them contending for +// the same sqlite file just adds lock pressure. The globalThis stash keeps +// dev hot-reload from leaking a new client on every recompile. +const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient }; + +const prisma = globalForPrisma.prisma ?? new PrismaClient(); + +if (process.env.NODE_ENV !== 'production') { + globalForPrisma.prisma = prisma; +} + +export default prisma; diff --git a/ui/src/server/settings.ts b/ui/src/server/settings.ts index 9c6abe6..7a0a675 100644 --- a/ui/src/server/settings.ts +++ b/ui/src/server/settings.ts @@ -1,10 +1,9 @@ -import { PrismaClient } from '@prisma/client'; +import prisma from '@/server/prisma'; import { defaultDatasetsFolder, defaultDataRoot } from '@/paths'; import { defaultTrainFolder } from '@/paths'; import NodeCache from 'node-cache'; const myCache = new NodeCache(); -const prisma = new PrismaClient(); export const flushCache = () => { myCache.flushAll();