feat: D3 foundation — retry schema, shared types, health client, backoff helper
- Add retry_count/next_retry_at to jobs table via guarded idempotent ALTER TABLE (PRAGMA table_info existence check, try/catch for safety on restart) - Add retryCount/nextRetryAt to Job type, rowToJob(), updateJob(), resetJob() - Add getHealth() returning structured WhisperHealth (status, gpu_name, vram_total_mb, model, queue_depth, model_state) distinct from existing checkHealth() boolean helper - Create retryWithBackoff() pure helper in src/lib/server/retry.ts with exponential backoff + jitter and onAttempt callback — no persistence owned - Tests: retry column read/write/reset, getHealth() smoke tests, retryWithBackoff() edge cases (success, failure, backoff timing, onAttempt)
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
listJobs,
|
||||
updateJob,
|
||||
setJobStatus,
|
||||
resetJob,
|
||||
savePushSubscription,
|
||||
getAllSubscriptions,
|
||||
deletePushSubscription
|
||||
@@ -107,6 +108,28 @@ describe('updateJob', () => {
|
||||
it('does nothing for an unknown id', () => {
|
||||
expect(() => updateJob({ id: 'no-such-id', title: 'Ghost' })).not.toThrow();
|
||||
});
|
||||
|
||||
it('stores and reads retryCount and nextRetryAt', () => {
|
||||
const job = createJob('src', 'retry test', 'auto');
|
||||
// Default retry_count is 0 (DEFAULT 0 in schema)
|
||||
expect(getJob(job.id)!.retryCount).toBe(0);
|
||||
expect(getJob(job.id)!.nextRetryAt).toBeNull();
|
||||
|
||||
const nextRetry = new Date(Date.now() + 60000).toISOString();
|
||||
updateJob({ id: job.id, retryCount: 2, nextRetryAt: nextRetry });
|
||||
const updated = getJob(job.id)!;
|
||||
expect(updated.retryCount).toBe(2);
|
||||
expect(updated.nextRetryAt).toBe(nextRetry);
|
||||
});
|
||||
|
||||
it('resetJob clears retry fields', () => {
|
||||
const job = createJob('src', 'reset retry', 'auto');
|
||||
updateJob({ id: job.id, retryCount: 3, nextRetryAt: '2026-07-08T12:00:00.000Z' });
|
||||
resetJob(job.id);
|
||||
const after = getJob(job.id)!;
|
||||
expect(after.retryCount).toBe(0);
|
||||
expect(after.nextRetryAt).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ── setJobStatus ──────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user