fix: give the worker a pg Pool and real transactions
The worker ran every job through a single pg Client while BullMQ was configured with concurrency: 10. A Client is one connection with one protocol stream and no queueing: ten concurrent jobs interleave on it, and any BEGIN/COMMIT is shared by all of them, so an unrelated job's failure can roll back another's work and a rollback can discard a third's committed intent. Switched to a Pool, added a small withTransaction(pool, fn) helper that takes a dedicated connection per transaction, and threaded a Queryable interface through the services so they accept either a pool or a pooled client. Both reprocess_artists merge blocks — the artist merge and the duplicate-album merge — now run inside withTransaction; previously a failure partway through left artists merged and their tracks unmoved. integrity.service and cleanup.service get only the constructor type change here so this commit compiles; their own fixes follow in the next two commits. cleanup.service's BEGIN/COMMIT-on-a-Pool is therefore still wrong at this commit and is replaced wholesale by the hard-delete commit. REVIEW-2026-07-30.md finding 4 (and the concurrency note in finding 3). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import { createReadStream } from 'fs';
|
||||
import { createHash } from 'crypto';
|
||||
import path from 'path';
|
||||
import mm from 'music-metadata';
|
||||
import { Client as PgClient } from 'pg';
|
||||
import type { Queryable } from './db.js';
|
||||
import { Queue } from 'bullmq';
|
||||
import { MetadataRefreshJob, ArtistSimilarityJob, ArtistImageJob, AlbumCoverJob } from './types.js';
|
||||
import { splitArtistNames, parseArtists } from './utils/artist-names.js';
|
||||
@@ -80,7 +80,7 @@ export class ScannerService {
|
||||
private enqueuedArtists = new Set<string>();
|
||||
private enqueuedAlbums = new Set<string>();
|
||||
|
||||
constructor(private pgClient: PgClient, private queue: Queue) {}
|
||||
constructor(private pgClient: Queryable, private queue: Queue) {}
|
||||
|
||||
async scanDirectory(directory: string) {
|
||||
console.log(`[Scanner] Starting scan in: ${directory}`);
|
||||
|
||||
Reference in New Issue
Block a user