Geert Rademakes b436d1dabc feat: implement immediate song document updates for perfect sync resilience
- Remove end-of-job cleanup phases from S3 sync and song matching jobs
- Update Song documents immediately after each successful match in both Phase 1 and Phase 2
- Ensure hasS3File flag is set to true immediately for each matched song
- Enable play buttons to appear instantly as songs are processed
- Make system perfectly resilient to interruptions - no orphaned files
- Allow seamless resume capability for long-running sync jobs
- Provide real-time availability of matched songs without waiting for job completion
- Maintain system consistency regardless of when sync gets interrupted
2025-08-07 23:36:30 +02:00

78 lines
1.9 KiB
TypeScript

import express from 'express';
import { backgroundJobService } from '../services/backgroundJobService.js';
const router = express.Router();
/**
* Start a new background job
*/
router.post('/start', async (req, res) => {
try {
const { type, options } = req.body;
if (!type || !['s3-sync', 'song-matching'].includes(type)) {
return res.status(400).json({ error: 'Invalid job type. Must be "s3-sync" or "song-matching"' });
}
console.log(`🚀 Starting background job: ${type}`);
const jobId = await backgroundJobService.startJob({ type, options });
res.json({
message: 'Background job started',
jobId,
type
});
} catch (error) {
console.error('Error starting background job:', error);
res.status(500).json({ error: 'Failed to start background job' });
}
});
/**
* Get job progress
*/
router.get('/progress/:jobId', async (req, res) => {
try {
const { jobId } = req.params;
const progress = backgroundJobService.getJobProgress(jobId);
if (!progress) {
return res.status(404).json({ error: 'Job not found' });
}
res.json(progress);
} catch (error) {
console.error('Error getting job progress:', error);
res.status(500).json({ error: 'Failed to get job progress' });
}
});
/**
* Get all jobs
*/
router.get('/jobs', async (req, res) => {
try {
const jobs = backgroundJobService.getAllJobs();
res.json({ jobs });
} catch (error) {
console.error('Error getting jobs:', error);
res.status(500).json({ error: 'Failed to get jobs' });
}
});
/**
* Clean up old jobs
*/
router.post('/cleanup', async (req, res) => {
try {
backgroundJobService.cleanupOldJobs();
res.json({ message: 'Old jobs cleaned up successfully' });
} catch (error) {
console.error('Error cleaning up jobs:', error);
res.status(500).json({ error: 'Failed to clean up jobs' });
}
});
export default router;