diff --git a/example/package.json b/example/package.json index cea0a791..4fdbbb6e 100644 --- a/example/package.json +++ b/example/package.json @@ -13,7 +13,7 @@ "license": "MIT", "dependencies": { "bee-queue": "^1.3.1", - "bull": "^3.20.1", + "bull": "^3.22.6", "bullmq": "^1.26.2", "express": "^4.17.1", "redis-server": "^1.2.2" diff --git a/public/dashboard.js b/public/dashboard.js index 8a4d3011..18cf5334 100644 --- a/public/dashboard.js +++ b/public/dashboard.js @@ -17,6 +17,11 @@ $(document).ready(() => { const r = window.confirm( `Retry job #${jobId} in queue "${queueHost}/${queueName}"?` ); + console.log( + `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/job/${encodeURIComponent(jobId)}` + ); if (r) { $.ajax({ method: 'PATCH', @@ -210,6 +215,12 @@ $(document).ready(() => { const job = JSON.stringify({name, data}); localStorage.setItem('arena:savedJob', job); const {queueHost, queueName} = window.arenaInitialPayload; + console.log( + 'nie', + `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/job` + ); $.ajax({ url: `${basePath}/api/queue/${encodeURIComponent( queueHost @@ -227,4 +238,59 @@ $(document).ready(() => { console.error(jqXHR.responseText); }); }); + + $('.js-pause-queue').on('click', function (e) { + e.preventDefault(); + $(this).prop('disabled', true); + const queueName = $(this).data('queue-name'); + const queueHost = $(this).data('queue-host'); + + const response = window.confirm( + `Do you really want to pause the queue "${queueHost}/${queueName}"?` + ); + if (response) { + $.ajax({ + method: 'PUT', + url: `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/pause`, + }) + .done(() => { + window.location.reload(); + }) + .fail((jqXHR) => { + window.alert(`Request failed, check console for error.`); + console.error(jqXHR.responseText); + }); + } else { + $(this).prop('disabled', false); + } + }); + + $('.js-resume-queue').on('click', function (e) { + e.preventDefault(); + const queueName = $(this).data('queue-name'); + const queueHost = $(this).data('queue-host'); + + const response = window.confirm( + `Do you want to resume the queue "${queueHost}/${queueName}"?` + ); + if (response) { + $.ajax({ + method: 'PUT', + url: `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/resume`, + }) + .done(() => { + window.location.reload(); + }) + .fail((jqXHR) => { + window.alert(`Request failed, check console for error.`); + console.error(jqXHR.responseText); + }); + } else { + $(this).prop('disabled', false); + } + }); }); diff --git a/src/server/views/api/index.js b/src/server/views/api/index.js index b2ad9235..a55ffe9a 100644 --- a/src/server/views/api/index.js +++ b/src/server/views/api/index.js @@ -7,6 +7,8 @@ const jobRemove = require('./jobRemove'); const bulkJobsPromote = require('./bulkJobsPromote'); const bulkJobsRemove = require('./bulkJobsRemove'); const bulkJobsRetry = require('./bulkJobsRetry'); +const queuePause = require('./queuePause'); +const queueResume = require('./queueResume'); router.post('/queue/:queueHost/:queueName/job', jobAdd); router.post('/queue/:queueHost/:queueName/job/bulk', bulkJobsRemove); @@ -14,6 +16,8 @@ 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.patch('/queue/:queueHost/:queueName/job/:id', jobRetry); +router.put('/queue/:queueHost/:queueName/pause', queuePause); +router.put('/queue/:queueHost/:queueName/resume', queueResume); router.delete('/queue/:queueHost/:queueName/job/:id', jobRemove); module.exports = router; diff --git a/src/server/views/api/queuePause.js b/src/server/views/api/queuePause.js new file mode 100644 index 00000000..e806f6ba --- /dev/null +++ b/src/server/views/api/queuePause.js @@ -0,0 +1,18 @@ +async function handler(req, res) { + const {queueName, queueHost} = req.params; + + const {Queues} = req.app.locals; + + const queue = await Queues.get(queueName, queueHost); + + if (!queue) return res.status(404).json({error: 'queue not found'}); + + try { + await queue.pause(); + } catch (err) { + return res.status(500).json({error: err.message}); + } + return res.sendStatus(200); +} + +module.exports = handler; diff --git a/src/server/views/api/queueResume.js b/src/server/views/api/queueResume.js new file mode 100644 index 00000000..de94756f --- /dev/null +++ b/src/server/views/api/queueResume.js @@ -0,0 +1,17 @@ +async function handler(req, res) { + const {queueName, queueHost} = req.params; + + const {Queues} = req.app.locals; + + const queue = await Queues.get(queueName, queueHost); + if (!queue) return res.status(404).json({error: 'queue not found'}); + + try { + await queue.resume(); + } catch (err) { + return res.status(500).json({error: err.message}); + } + return res.sendStatus(200); +} + +module.exports = handler; diff --git a/src/server/views/dashboard/queueDetails.js b/src/server/views/dashboard/queueDetails.js index daccaed5..31696262 100644 --- a/src/server/views/dashboard/queueDetails.js +++ b/src/server/views/dashboard/queueDetails.js @@ -22,9 +22,11 @@ async function handler(req, res) { jobCounts = await queue.getJobCounts(); } const stats = await QueueHelpers.getStats(queue); + const isPaused = await QueueHelpers.isPaused(queue); return res.render('dashboard/templates/queueDetails', { basePath, + isPaused, queueName, queueHost, queueIsBee: !!queue.IS_BEE, diff --git a/src/server/views/dashboard/templates/queueDetails.hbs b/src/server/views/dashboard/templates/queueDetails.hbs index abd3262a..4f7c6603 100644 --- a/src/server/views/dashboard/templates/queueDetails.hbs +++ b/src/server/views/dashboard/templates/queueDetails.hbs @@ -1,5 +1,19 @@

Queue {{ queueHost }}/{{ queueName }}

+{{#unless queueIsBee}} +{{#if isPaused}} + +{{else}} + +{{/if}} +{{/unless}} +
@@ -13,7 +27,8 @@
{{#unless queueIsBee}} - + {{/unless}}
Create
@@ -39,10 +54,10 @@
{{#each stats}} - - - - + + + + {{/each}}
{{ @key }}{{ this }}
{{ @key }}{{ this }}
@@ -51,14 +66,14 @@
{{#contentFor 'sidebar'}} -
  • Queues Overview
  • -
  • Queue {{ queueHost }}/{{ queueName }}
  • +
  • Queues Overview
  • +
  • Queue {{ queueHost }}/{{ queueName }}
  • {{/contentFor}} {{#contentFor 'script'}} - window.jsonEditor = new JSONEditor(document.getElementById('jsoneditor'), { modes: ['code','tree','text'] }); - window.arenaInitialPayload = { - queueHost: "{{ queueHost }}", - queueName: "{{ queueName }}" - }; -{{/contentFor}} +window.jsonEditor = new JSONEditor(document.getElementById('jsoneditor'), { modes: ['code','tree','text'] }); +window.arenaInitialPayload = { +queueHost: "{{ queueHost }}", +queueName: "{{ queueName }}" +}; +{{/contentFor}} \ No newline at end of file diff --git a/src/server/views/helpers/queueHelpers.js b/src/server/views/helpers/queueHelpers.js index 12a29822..2e0f2e00 100644 --- a/src/server/views/helpers/queueHelpers.js +++ b/src/server/views/helpers/queueHelpers.js @@ -46,6 +46,10 @@ const Helpers = { return stats; }, + isPaused: async function (queue) { + return queue.isPaused(); + }, + _usefulMetrics: [ 'redis_version', 'total_system_memory',