pop method
Pops the next available job from the queue atomically.
Implementations MUST guarantee that no two workers can receive
the same job (distributed lock / atomic dequeue).
Returns null if the queue is empty or no jobs are available.
Implementation
@override
Future<Job?> pop([String queue = 'default']) async {
// Atomic dequeue with distributed locking:
// SELECT ... FOR UPDATE SKIP LOCKED ensures no two workers get the same row.
final result = await _db.query('''
UPDATE $_table
SET status = 'processing', reserved_by = @workerId
WHERE id = (
SELECT id FROM $_table
WHERE queue = @queue
AND status = 'pending'
AND (available_at IS NULL OR available_at <= NOW())
ORDER BY created_at ASC
LIMIT 1
FOR UPDATE SKIP LOCKED
)
RETURNING *
''', {
'queue': queue,
'workerId': workerId,
});
if (result.rows.isEmpty) return null;
final row = _JobRow.fromRow(result.rows.first);
return _hydrateJob(row);
}