Compare commits
No commits in common. "2b85fb49df8d9cf11dfd896a16c92c93db14adf8" and "6322b61a046affad61b9eb863d039d0b412a55ce" have entirely different histories.
2b85fb49df
...
6322b61a04
1 changed files with 6 additions and 24 deletions
|
|
@ -82,19 +82,11 @@ function Jobs({ navigate }) {
|
||||||
.catch(e => alert('Retry failed: ' + e.message));
|
.catch(e => alert('Retry failed: ' + e.message));
|
||||||
}, [refresh]);
|
}, [refresh]);
|
||||||
|
|
||||||
// One handler covers cancel (running) AND delete (queued / done / failed).
|
const handleDelete = React.useCallback((job) => {
|
||||||
// BullMQ's job.remove() — what the API calls — works on any state, so a
|
if (!window.confirm('Remove this job from the queue?')) return;
|
||||||
// stalled-active job (worker died mid-process, holding a concurrency slot)
|
|
||||||
// gets yanked and the next queued job runs. mode just changes the prompt
|
|
||||||
// copy so the operator knows what they're doing.
|
|
||||||
const handleDelete = React.useCallback((job, mode) => {
|
|
||||||
const msg = mode === 'cancel'
|
|
||||||
? 'Cancel this running ' + job.kind + ' job?\n\nThe worker may run a few seconds longer in the background, but its result will be discarded and the queue slot frees up immediately.'
|
|
||||||
: 'Remove this ' + job.status + ' ' + job.kind + ' job from the queue?';
|
|
||||||
if (!window.confirm(msg)) return;
|
|
||||||
window.ZAMPP_API.fetch('/jobs/' + job.id, { method: 'DELETE' })
|
window.ZAMPP_API.fetch('/jobs/' + job.id, { method: 'DELETE' })
|
||||||
.then(() => setJobs(prev => prev.filter(j => j.id !== job.id)))
|
.then(() => setJobs(prev => prev.filter(j => j.id !== job.id)))
|
||||||
.catch(e => alert((mode === 'cancel' ? 'Cancel' : 'Delete') + ' failed: ' + e.message));
|
.catch(e => alert('Delete failed: ' + e.message));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Retry every failed job at once. Useful after a transient infra issue
|
// Retry every failed job at once. Useful after a transient infra issue
|
||||||
|
|
@ -229,22 +221,12 @@ function JobRow({ job, onRetry, onDelete }) {
|
||||||
})()}
|
})()}
|
||||||
</div>
|
</div>
|
||||||
<div><span className={'badge ' + (job.priority === 'high' ? 'warning' : 'outline')}>{job.priority}</span></div>
|
<div><span className={'badge ' + (job.priority === 'high' ? 'warning' : 'outline')}>{job.priority}</span></div>
|
||||||
<div style={{ display: 'flex', gap: 4, justifyContent: 'flex-end' }}>
|
<div style={{ display: 'flex', gap: 4 }}>
|
||||||
{job.status === 'failed' && (
|
{job.status === 'failed' && (
|
||||||
<button className="btn ghost sm" onClick={() => onRetry(job)}><Icon name="refresh" />Retry</button>
|
<button className="btn ghost sm" onClick={() => onRetry(job)}><Icon name="refresh" />Retry</button>
|
||||||
)}
|
)}
|
||||||
{job.status === 'running' && (
|
{(job.status === 'queued' || job.status === 'done') && (
|
||||||
/* Cancel a stalled-active job — frees the BullMQ concurrency slot
|
<button className="icon-btn" title="Remove job" onClick={() => onDelete(job)}><Icon name="x" /></button>
|
||||||
so anything queued behind it can run. The worker may finish in
|
|
||||||
the background but its result is discarded. */
|
|
||||||
<button className="btn ghost sm" onClick={() => onDelete(job, 'cancel')}
|
|
||||||
style={{ color: 'var(--danger)' }} title="Cancel this running job and free its queue slot">
|
|
||||||
<Icon name="x" />Cancel
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{(job.status === 'queued' || job.status === 'done' || job.status === 'failed') && (
|
|
||||||
<button className="icon-btn" title="Remove job from the queue"
|
|
||||||
onClick={() => onDelete(job, 'delete')}><Icon name="x" /></button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue