Skip to content

Commit

Permalink
feat(bull): support removing repeatable jobs (#574)
Browse files Browse the repository at this point in the history
  • Loading branch information
roggervalf authored Oct 18, 2022
1 parent 5e40ca1 commit 29528cf
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 0 deletions.
3 changes: 3 additions & 0 deletions example/bull.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ async function main() {
const delayedJob = await queue.add({}, {delay: 60 * 1000});
delayedJob.log('Log message');

// add repeatable jobs
await queue.add({}, {repeat: {cron: '15 * * * *'}});

const app = Arena(
{
Bull,
Expand Down
36 changes: 36 additions & 0 deletions public/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,42 @@ $(document).ready(() => {
}
});

// Set up individual "remove repeatable job" handler
$('.js-remove-repeatable-job').on('click', function (e) {
e.preventDefault();
$(this).prop('disabled', true);

const jobId = $(this).data('job-id');
const queueName = $(this).data('queue-name');
const queueHost = $(this).data('queue-host');
const jobState = $(this).data('job-state');

const confirmationResponse = window.confirm(
`Remove repeatable job #${jobId} in queue "${queueHost}/${queueName}"?`
);
if (confirmationResponse) {
$.ajax({
method: 'DELETE',
url: `${basePath}/api/queue/${encodeURIComponent(
queueHost
)}/${encodeURIComponent(queueName)}/repeatable/job/${encodeURIComponent(
jobId
)}`,
})
.done(() => {
window.location.href = `${basePath}/${encodeURIComponent(
queueHost
)}/${encodeURIComponent(queueName)}/${jobState}`;
})
.fail((jqXHR) => {
window.alert(`Request failed, check console for error.`);
console.error(jqXHR.responseText);
});
} else {
$(this).prop('disabled', false);
}
});

// Set up "select all jobs" button handler
$('.js-select-all-jobs').change(function () {
const $jobBulkCheckboxes = $('.js-bulk-job');
Expand Down
5 changes: 5 additions & 0 deletions src/server/views/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const jobAdd = require('./jobAdd');
const jobPromote = require('./jobPromote');
const jobRetry = require('./jobRetry');
const jobRemove = require('./jobRemove');
const repeatableJobRemove = require('./repeatableJobRemove');
const bulkJobsPromote = require('./bulkJobsPromote');
const bulkJobsRemove = require('./bulkJobsRemove');
const bulkJobsRetry = require('./bulkJobsRetry');
Expand All @@ -19,6 +20,10 @@ router.post('/queue/:queueHost/:queueName/job/bulk', bulkJobsRemove);
router.patch('/queue/:queueHost/:queueName/job/bulk', bulkJobsRetry);
router.patch('/queue/:queueHost/:queueName/delayed/job/bulk', bulkJobsPromote);
router.patch('/queue/:queueHost/:queueName/delayed/job/:id', jobPromote);
router.delete(
'/queue/:queueHost/:queueName/repeatable/job/:id',
repeatableJobRemove
);
router.patch('/queue/:queueHost/:queueName/job/:id', jobRetry);
router.put('/queue/:queueHost/:queueName/pause', queuePause);
router.put('/queue/:queueHost/:queueName/resume', queueResume);
Expand Down
23 changes: 23 additions & 0 deletions src/server/views/api/repeatableJobRemove.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
async function handler(req, res) {
const {queueName, queueHost, id} = req.params;

const {Queues} = req.app.locals;
const queue = await Queues.get(queueName, queueHost);
if (!queue) return res.status(404).send({error: 'queue not found'});

const job = await queue.getJob(id);
if (!job) return res.status(404).send({error: 'job not found'});

try {
await queue.removeRepeatableByKey(job.opts.repeat.key);
return res.sendStatus(200);
} catch (e) {
const body = {
error: 'queue error',
details: e.stack,
};
return res.status(500).send(body);
}
}

module.exports = handler;
2 changes: 2 additions & 0 deletions src/server/views/dashboard/jobDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ async function handler(req, res) {
job.showRetryButton = !queue.IS_BEE || jobState === 'failed';
job.retryButtonText = jobState === 'failed' ? 'Retry' : 'Trigger';
job.showPromoteButton = !queue.IS_BEE && jobState === 'delayed';
job.showDeleteRepeatableButton =
queue.IS_BULL && job.opts.repeat && job.opts.repeat.key;
const stacktraces = queue.IS_BEE ? job.options.stacktraces : job.stacktrace;

if (!queue.IS_BEE) {
Expand Down
2 changes: 2 additions & 0 deletions src/server/views/dashboard/queueJobsByState.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ async function _html(req, res) {
job.showRetryButton = !queue.IS_BEE || jobState === 'failed';
job.retryButtonText = jobState === 'failed' ? 'Retry' : 'Trigger';
job.showPromoteButton = !queue.IS_BEE && jobState === 'delayed';
job.showDeleteRepeatableButton =
queue.IS_BULL && job.opts.repeat && job.opts.repeat.key;
job.parent = JobHelpers.getKeyProperties(job.parentKey);
}

Expand Down
7 changes: 7 additions & 0 deletions src/server/views/partials/dashboard/jobDetails.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
</button>
{{/if}}

{{#if showDeleteRepeatableButton}}
<button class="btn btn-danger js-remove-repeatable-job" data-queue-host="{{ queueHost }}" data-queue-name="{{ queueName }}"
data-job-id="{{ this.id }}" data-job-state="{{ jobState }}">
Remove Repeatable
</button>
{{/if}}

<div class="row">
<div class="col-sm-3">
<h5>State</h5>
Expand Down

0 comments on commit 29528cf

Please sign in to comment.