Fix: Add batch processing to prevent timeout on large song libraries

This commit is contained in:
Hördle Bot
2025-11-22 12:11:11 +01:00
parent 15746f404a
commit 10cab22cfe
2 changed files with 85 additions and 24 deletions

View File

@@ -6,6 +6,7 @@ const prisma = new PrismaClient();
const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY;
const OPENROUTER_MODEL = 'anthropic/claude-3.5-haiku';
const BATCH_SIZE = 20; // Process 20 songs at a time to avoid timeouts
interface CategorizeResult {
songId: number;
@@ -14,7 +15,7 @@ interface CategorizeResult {
assignedGenres: string[];
}
export async function POST() {
export async function POST(request: Request) {
try {
if (!OPENROUTER_API_KEY) {
return Response.json(
@@ -23,7 +24,30 @@ export async function POST() {
);
}
// Get offset from request body (for batch processing)
const body = await request.json().catch(() => ({}));
const offset = body.offset || 0;
// Fetch all songs without genres
const totalUncategorized = await prisma.song.count({
where: {
genres: {
none: {}
}
}
});
if (totalUncategorized === 0) {
return Response.json({
message: 'No uncategorized songs found',
results: [],
hasMore: false,
totalUncategorized: 0,
processed: 0
});
}
// Fetch batch of songs
const uncategorizedSongs = await prisma.song.findMany({
where: {
genres: {
@@ -32,16 +56,11 @@ export async function POST() {
},
include: {
genres: true
}
},
take: BATCH_SIZE,
skip: offset
});
if (uncategorizedSongs.length === 0) {
return Response.json({
message: 'No uncategorized songs found',
results: []
});
}
// Fetch all available genres
const allGenres = await prisma.genre.findMany({
orderBy: { name: 'asc' }
@@ -56,7 +75,7 @@ export async function POST() {
const results: CategorizeResult[] = [];
// Process each song
// Process each song in this batch
for (const song of uncategorizedSongs) {
try {
const genreNames = allGenres.map(g => g.name);
@@ -147,10 +166,15 @@ Your response:`;
}
}
const newOffset = offset + BATCH_SIZE;
const hasMore = newOffset < totalUncategorized;
return Response.json({
message: `Processed ${uncategorizedSongs.length} songs, categorized ${results.length}`,
totalProcessed: uncategorizedSongs.length,
totalCategorized: results.length,
message: `Processed ${uncategorizedSongs.length} songs in this batch, categorized ${results.length}`,
totalUncategorized,
processed: Math.min(newOffset, totalUncategorized),
hasMore,
nextOffset: hasMore ? newOffset : null,
results
});