feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
.bg-green {
background-color: #f0ffeb;
}
.dataTables_wrapper {
border: 1px solid #c7ecb8;
}
.dataTables_filter input {
width: 50%;
text-indent: 5px;
}
.dataTables_length {
margin: 10px;
}
div.dataTables_wrapper .dataTables_filter input {
width: 100%;
margin: 10px;
border: 1px solid #c7ecb8;
}
.dataTables_info {
padding: 5px;
}
@media (min-width: 768px) {
div.dataTables_wrapper .dataTables_filter input {
width: 500px;
}
}
.overflow-auto {
max-width: 400px;
text-overflow: ellipsis;
}
.overflow-auto::-webkit-scrollbar {
display: none;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,692 @@
/*jslint browser: true */
/*global $, WebSocket, jQuery */
var flower = (function () {
"use strict";
var alertContainer = document.getElementById('alert-container');
function show_alert(message, type) {
var wrapper = document.createElement('div');
wrapper.innerHTML = `
<div class="alert alert-${type} alert-dismissible" role="alert">
<div>${message}</div>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>`;
alertContainer.appendChild(wrapper);
}
function url_prefix() {
var prefix = $('#url_prefix').val();
if (prefix) {
prefix = prefix.replace(/\/+$/, '');
if (prefix.startsWith('/')) {
return prefix;
} else {
return '/' + prefix;
}
}
return '';
}
//https://github.com/DataTables/DataTables/blob/1.10.11/media/js/jquery.dataTables.js#L14882
function htmlEscapeEntities(d) {
return typeof d === 'string' ?
d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
d;
}
function active_page(name) {
var pathname = $(location).attr('pathname');
if (name === '/') {
return pathname === (url_prefix() + name);
}
else {
return pathname.startsWith(url_prefix() + name);
}
}
$('#worker-refresh').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'GET',
url: url_prefix() + '/api/workers',
dataType: 'json',
data: {
workername: unescape(workername),
refresh: 1
},
success: function (data) {
show_alert(data.message || 'Successfully refreshed', 'success');
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-refresh-all').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
$.ajax({
type: 'GET',
url: url_prefix() + '/api/workers',
dataType: 'json',
data: {
refresh: 1
},
success: function (data) {
show_alert(data.message || 'Refreshed All Workers', 'success');
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-restart').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/restart/' + workername,
dataType: 'json',
data: {
workername: workername
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-shutdown').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/shutdown/' + workername,
dataType: 'json',
data: {
workername: workername
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-grow').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
grow_size = $('#pool-size option:selected').html();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/grow/' + workername,
dataType: 'json',
data: {
'workername': workername,
'n': grow_size,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-shrink').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
shrink_size = $('#pool-size option:selected').html();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/shrink/' + workername,
dataType: 'json',
data: {
'workername': workername,
'n': shrink_size,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-autoscale').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
min = $('#min-autoscale').val(),
max = $('#max-autoscale').val();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/autoscale/' + workername,
dataType: 'json',
data: {
'workername': workername,
'min': min,
'max': max,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-add-consumer').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
queue = $('#add-consumer-name').val();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/queue/add-consumer/' + workername,
dataType: 'json',
data: {
'workername': workername,
'queue': queue,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-queues').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
if (!event.target.id.startsWith("worker-cancel-consumer")) {
return;
}
var workername = $('#workername').text(),
queue = $(event.target).closest("tr").children("td:eq(0)").text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/queue/cancel-consumer/' + workername,
dataType: 'json',
data: {
'workername': workername,
'queue': queue,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#limits-table').on('click', function (event) {
if (event.target.id.startsWith("task-timeout-")) {
var timeout = parseInt($(event.target).siblings().closest("input").val()),
type = $(event.target).text().toLowerCase(),
taskname = $(event.target).closest("tr").children("td:eq(0)").text(),
post_data = {'workername': $('#workername').text()};
taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx]
post_data[type] = timeout;
if (!Number.isInteger(timeout)) {
show_alert("Invalid timeout value", "danger");
return;
}
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/timeout/' + taskname,
dataType: 'json',
data: post_data,
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert($(data.responseText).text(), "danger");
}
});
} else if (event.target.id.startsWith("task-rate-limit-")) {
var taskname = $(event.target).closest("tr").children("td:eq(0)").text(),
workername = $('#workername').text(),
ratelimit = parseInt($(event.target).prev().val());
taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx]
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/rate-limit/' + taskname,
dataType: 'json',
data: {
'workername': workername,
'ratelimit': ratelimit,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
}
});
$('#task-revoke').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var taskid = $('#taskid').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/revoke/' + taskid,
dataType: 'json',
data: {
'terminate': false,
},
success: function (data) {
show_alert(data.message, "success");
document.getElementById("task-revoke").disabled = true;
setTimeout(function() {location.reload();}, 5000);
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#task-terminate').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var taskid = $('#taskid').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/revoke/' + taskid,
dataType: 'json',
data: {
'terminate': true,
},
success: function (data) {
show_alert(data.message, "success");
document.getElementById("task-terminate").disabled = true;
setTimeout(function() {location.reload();}, 5000);
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
function sum(a, b) {
return parseInt(a, 10) + parseInt(b, 10);
}
function format_time(timestamp) {
var time = $('#time').val(),
prefix = time.startsWith('natural-time') ? 'natural-time' : 'time',
tz = time.substr(prefix.length + 1) || 'UTC';
if (prefix === 'natural-time') {
return moment.unix(timestamp).tz(tz).fromNow();
}
return moment.unix(timestamp).tz(tz).format('YYYY-MM-DD HH:mm:ss.SSS');
}
function isColumnVisible(name) {
var columns = $('#columns').val();
if (columns === "all")
return true;
if (columns) {
columns = columns.split(',').map(function (e) {
return e.trim();
});
return columns.indexOf(name) !== -1;
}
return true;
}
$.urlParam = function (name) {
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
return (results && results[1]) || 0;
};
$(document).ready(function () {
//https://github.com/twitter/bootstrap/issues/1768
var shiftWindow = function () {
scrollBy(0, -50);
};
if (location.hash) {
shiftWindow();
}
window.addEventListener("hashchange", shiftWindow);
// Make bootstrap tabs persistent
$(document).ready(function () {
if (location.hash !== '') {
$('a[href="' + location.hash + '"]').tab('show');
}
// Listen for tab shown events and update the URL hash fragment accordingly
$('.nav-tabs a[data-bs-toggle="tab"]').on('shown.bs.tab', function (event) {
const tabPaneId = $(event.target).attr('href').substr(1);
if (tabPaneId) {
window.location.hash = tabPaneId;
}
});
});
});
$(document).ready(function () {
if (!active_page('/') && !active_page('/workers')) {
return;
}
$('#workers-table').DataTable({
rowId: 'name',
searching: true,
select: false,
paging: true,
scrollCollapse: true,
lengthMenu: [15, 30, 50, 100],
pageLength: 15,
language: {
lengthMenu: 'Show _MENU_ workers',
info: 'Showing _START_ to _END_ of _TOTAL_ workers',
infoFiltered: '(filtered from _MAX_ total workers)'
},
ajax: url_prefix() + '/workers?json=1',
order: [
[1, "des"]
],
footerCallback: function( tfoot, data, start, end, display ) {
var api = this.api();
var columns = {2:"STARTED", 3:"", 4:"FAILURE", 5:"SUCCESS", 6:"RETRY"};
for (const [column, state] of Object.entries(columns)) {
var total = api.column(column).data().reduce(sum, 0);
var footer = total;
if (total !== 0) {
let queryParams = (state !== '' ? `?state=${state}` : '');
footer = '<a href="' + url_prefix() + '/tasks' + queryParams + '">' + total + '</a>';
}
$(api.column(column).footer()).html(footer);
}
},
columnDefs: [{
targets: 0,
data: 'hostname',
type: 'natural',
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/worker/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 1,
data: 'status',
className: "text-center",
width: "10%",
render: function (data, type, full, meta) {
if (data) {
return '<span class="badge bg-success">Online</span>';
} else {
return '<span class="badge bg-secondary">Offline</span>';
}
}
}, {
targets: 2,
data: 'active',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 3,
data: 'task-received',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 4,
data: 'task-failed',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 5,
data: 'task-succeeded',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 6,
data: 'task-retried',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 7,
data: 'loadavg',
width: "10%",
className: "text-center text-nowrap",
render: function (data, type, full, meta) {
if (!full.status) {
return 'N/A';
}
if (Array.isArray(data)) {
return data.join(', ');
}
return data;
}
}, ],
});
var autorefresh_interval = $.urlParam('autorefresh') || 1;
if (autorefresh !== 0) {
setInterval( function () {
$('#workers-table').DataTable().ajax.reload(null, false);
}, autorefresh_interval * 1000);
}
});
$(document).ready(function () {
if (!active_page('/tasks')) {
return;
}
$('#tasks-table').DataTable({
rowId: 'uuid',
searching: true,
scrollX: true,
scrollCollapse: true,
processing: true,
serverSide: true,
colReorder: true,
lengthMenu: [15, 30, 50, 100],
pageLength: 15,
language: {
lengthMenu: 'Show _MENU_ tasks',
info: 'Showing _START_ to _END_ of _TOTAL_ tasks',
infoFiltered: '(filtered from _MAX_ total tasks)'
},
ajax: {
type: 'POST',
url: url_prefix() + '/tasks/datatable'
},
order: [
[7, "desc"]
],
oSearch: {
"sSearch": $.urlParam('state') ? 'state:' + $.urlParam('state') : ''
},
columnDefs: [{
targets: 0,
data: 'name',
visible: isColumnVisible('name'),
render: function (data, type, full, meta) {
return data;
}
}, {
targets: 1,
data: 'uuid',
visible: isColumnVisible('uuid'),
orderable: false,
className: "text-nowrap",
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/task/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 2,
data: 'state',
visible: isColumnVisible('state'),
className: "text-center",
render: function (data, type, full, meta) {
switch (data) {
case 'SUCCESS':
return '<span class="badge bg-success">' + data + '</span>';
case 'FAILURE':
return '<span class="badge bg-danger">' + data + '</span>';
default:
return '<span class="badge bg-secondary">' + data + '</span>';
}
}
}, {
targets: 3,
data: 'args',
className: "text-nowrap overflow-auto",
visible: isColumnVisible('args'),
render: htmlEscapeEntities
}, {
targets: 4,
data: 'kwargs',
className: "text-nowrap overflow-auto",
visible: isColumnVisible('kwargs'),
render: htmlEscapeEntities
}, {
targets: 5,
data: 'result',
visible: isColumnVisible('result'),
className: "text-nowrap overflow-auto",
render: htmlEscapeEntities
}, {
targets: 6,
data: 'received',
className: "text-nowrap",
visible: isColumnVisible('received'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 7,
data: 'started',
className: "text-nowrap",
visible: isColumnVisible('started'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 8,
data: 'runtime',
className: "text-center",
visible: isColumnVisible('runtime'),
render: function (data, type, full, meta) {
return data ? data.toFixed(2) : data;
}
}, {
targets: 9,
data: 'worker',
visible: isColumnVisible('worker'),
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/worker/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 10,
data: 'exchange',
visible: isColumnVisible('exchange')
}, {
targets: 11,
data: 'routing_key',
visible: isColumnVisible('routing_key')
}, {
targets: 12,
data: 'retries',
className: "text-center",
visible: isColumnVisible('retries')
}, {
targets: 13,
data: 'revoked',
className: "text-nowrap",
visible: isColumnVisible('revoked'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 14,
data: 'exception',
className: "text-nowrap",
visible: isColumnVisible('exception')
}, {
targets: 15,
data: 'expires',
visible: isColumnVisible('expires')
}, {
targets: 16,
data: 'eta',
visible: isColumnVisible('eta')
}, ],
});
});
}(jQuery));
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,523 @@
{
"tags": [
],
"paths": {
"\/api\/tasks": {
"get": {
"responses": {
"200": {
"description": "Result"
}
},
"description": "List tasks",
"parameters": [
{
"name": "limit",
"in": "query",
"description": "the maximum number of tasks",
"required": false,
"format": "int32",
"type": "integer"
},
{
"name": "workername",
"in": "query",
"description": "filter task by workername",
"required": false,
"type": "string"
},
{
"name": "taskname",
"in": "query",
"description": "filter task by taskname",
"required": false,
"type": "string"
},
{
"name": "state",
"in": "query",
"description": "filter task by state",
"required": false,
"type": "string"
}
]
}
},
"\/api\/task\/types": {
"get": {
"responses": {
"200": {
"description": "result"
}
},
"description": "List (seen) task types"
}
},
"\/api\/queues\/length": {
"get": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Get queue lengths"
}
},
"\/api\/task\/info\/{taskid}": {
"get": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Get task info",
"parameters": [
{
"$ref": "#\/parameters\/taskid"
}
]
}
},
"\/api\/task\/apply\/{taskname}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Execute a task by name and wait results",
"parameters": [
{
"$ref": "#\/parameters\/taskname"
},
{
"schema": {
"type": "object",
"properties": {
"kwargs": {
"type": "object"
},
"args": {
"type": "array"
}
}
},
"name": "args",
"description": "the dictionary of args and kwargs",
"in": "body"
}
]
}
},
"\/api\/task\/async-apply\/{taskname}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Execute a task",
"parameters": [
{
"$ref": "#\/parameters\/taskname"
},
{
"schema": {
"type": "object",
"properties": {
"kwargs": {
"type": "object"
},
"args": {
"type": "array"
},
"options": {
"type": "object"
}
}
},
"name": "args",
"description": "the dictionary of args, kwargs, and apply-async options",
"in": "body"
}
]
}
},
"\/api\/task\/send-task\/{taskname}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Execute a task by name (Doesn't require a task source)",
"parameters": [
{
"$ref": "#\/parameters\/taskname"
},
{
"schema": {
"type": "object",
"properties": {
"kwargs": {
"type": "object"
},
"args": {
"type": "array"
}
}
},
"name": "args",
"description": "the dictionary of args, and kwargs",
"in": "body"
}
]
}
},
"\/api\/task\/result\/{taskid}": {
"get": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Get a task result",
"parameters": [
{
"$ref": "#\/parameters\/taskid"
},
{
"name": "timeout",
"in": "query",
"description": "how long to wait, in seconds, before the operation times out",
"required": false,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/task\/abort\/{taskid}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Abort a running task",
"parameters": [
{
"$ref": "#\/parameters\/taskid"
}
]
}
},
"\/api\/task\/timeout\/{taskname}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Change soft and hard time limits for a task",
"parameters": [
{
"$ref": "#\/parameters\/taskname"
},
{
"name": "workername",
"in": "query",
"description": "the name of a worker",
"required": true,
"type": "string"
},
{
"name": "soft",
"in": "query",
"description": "the soft timeout limit",
"required": false,
"format": "int32",
"type": "integer"
},
{
"name": "hard",
"in": "query",
"description": "the hard timeout limit",
"required": false,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/task\/rate-limit\/{taskname}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Change rate limit for a task",
"parameters": [
{
"$ref": "#\/parameters\/taskname"
},
{
"name": "workername",
"in": "query",
"description": "the name of a worker",
"required": true,
"type": "string"
},
{
"name": "rateLimit",
"in": "query",
"description": "the rate limit to apply",
"required": true,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/task\/revoke\/{taskid}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Revoke a task",
"parameters": [
{
"$ref": "#\/parameters\/taskid"
},
{
"name": "terminate",
"in": "query",
"description": "terminate the task if it is running",
"required": false,
"type": "boolean"
}
]
}
},
"\/api\/workers": {
"get": {
"responses": {
"200": {
"description": "result"
}
},
"description": "List workers",
"parameters": [
{
"name": "refresh",
"in": "query",
"description": "run inspect to get updated list of workers",
"required": false,
"type": "boolean"
},
{
"name": "workername",
"in": "query",
"description": "get info for workername",
"required": false,
"type": "string"
},
{
"name": "status",
"description": "only get worker status info",
"in": "query",
"type": "boolean"
}
]
}
},
"\/api\/worker\/shutdown\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Shut down a worker",
"parameters": [
{
"$ref": "#\/parameters\/workername"
}
]
}
},
"\/api\/worker\/pool\/restart\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Restart a worker's pool",
"parameters": [
{
"$ref": "#\/parameters\/workername"
}
]
}
},
"\/api\/worker\/pool\/grow\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Grow a worker's pool",
"parameters": [
{
"$ref": "#\/parameters\/workername"
},
{
"name": "n",
"in": "query",
"description": "number of pool processes to grow, default is 1",
"required": false,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/worker\/pool\/shrink\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Shrink a worker's pool",
"parameters": [
{
"$ref": "#\/parameters\/workername"
},
{
"name": "n",
"in": "query",
"description": "number of pool processes to shrink, default is 1",
"required": false,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/worker\/pool\/autoscale\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Autoscale a worker pool",
"parameters": [
{
"$ref": "#\/parameters\/workername"
},
{
"name": "min",
"in": "query",
"description": "minimum number of pool processes",
"required": false,
"format": "int32",
"type": "integer"
},
{
"name": "max",
"in": "query",
"description": "maximum number of pool processes",
"required": false,
"format": "int32",
"type": "integer"
}
]
}
},
"\/api\/worker\/queue\/add-consumer\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Start consuming from a queue",
"parameters": [
{
"$ref": "#\/parameters\/workername"
},
{
"name": "queue",
"in": "query",
"description": "the name of a queue",
"required": true,
"type": "string"
}
]
}
},
"\/api\/worker\/queue\/cancel-consumer\/{workername}": {
"post": {
"responses": {
"200": {
"description": "result"
}
},
"description": "Stop consuming from a queue",
"parameters": [
{
"$ref": "#\/parameters\/workername"
},
{
"name": "queue",
"in": "query",
"description": "the name of a queue",
"required": true,
"type": "string"
}
]
}
}
},
"parameters": {
"taskid": {
"type": "string",
"in": "path",
"description": "The task id",
"required": true,
"name": "taskid"
},
"workername": {
"type": "string",
"in": "path",
"description": "The worker name",
"required": true,
"name": "workername"
},
"taskname": {
"type": "string",
"in": "path",
"description": "The task name",
"required": true,
"name": "taskname"
}
},
"info": {
"description": "The flower API spec",
"version": "1.0.0-dev",
"title": "Flower"
},
"definitions": {
},
"swagger": "2.0"
}