diff --git a/flower/static/js/flower.js b/flower/static/js/flower.js index 992f0d65d..dc609b866 100644 --- a/flower/static/js/flower.js +++ b/flower/static/js/flower.js @@ -468,6 +468,17 @@ var flower = (function () { } }, { targets: 1, + data: 'active_queues', + className: "text-center", + render: function (data, type, full, meta) { + if (Array.isArray(data)) { + return data.map(x => x['name']).join(', '); + } else { + return ' '; + } + } + }, { + targets: 2, data: 'status', className: "text-center", width: "10%", @@ -479,37 +490,37 @@ var flower = (function () { } } }, { - targets: 2, + targets: 3, data: 'active', className: "text-center", width: "10%", defaultContent: 0 }, { - targets: 3, + targets: 4, data: 'task-received', className: "text-center", width: "10%", defaultContent: 0 }, { - targets: 4, + targets: 5, data: 'task-failed', className: "text-center", width: "10%", defaultContent: 0 }, { - targets: 5, + targets: 6, data: 'task-succeeded', className: "text-center", width: "10%", defaultContent: 0 }, { - targets: 6, + targets: 7, data: 'task-retried', className: "text-center", width: "10%", defaultContent: 0 }, { - targets: 7, + targets: 8, data: 'loadavg', width: "10%", className: "text-center text-nowrap", diff --git a/flower/templates/workers.html b/flower/templates/workers.html index 2e9d849db..f26c0eb3a 100644 --- a/flower/templates/workers.html +++ b/flower/templates/workers.html @@ -11,6 +11,7 @@ Worker + Queues Status Active Processed @@ -24,6 +25,7 @@ {% for name, info in workers.items() %} {{ name }} + {{ " ,".join(map(lambda queue: queue['name'], info.get('active_queues', []))) }} {{ info.get('status', None) }} {{ info.get('active', 0) or 0 }} {{ info.get('task-received', 0) }} diff --git a/flower/views/workers.py b/flower/views/workers.py index defd0469a..d9953b9eb 100644 --- a/flower/views/workers.py +++ b/flower/views/workers.py @@ -46,9 +46,10 @@ async def get(self): if name not in events.workers: continue worker = events.workers[name] + full_worker_info = self.application.workers.get(name, {}) info = dict(values) info.update(self._as_dict(worker)) - info.update(status=worker.alive) + info.update({'status': worker.alive, 'active_queues': full_worker_info.get('active_queues', [])}) workers[name] = info if options.purge_offline_workers is not None: diff --git a/tests/unit/views/test_workers.py b/tests/unit/views/test_workers.py index 07d37c53c..61b75addd 100644 --- a/tests/unit/views/test_workers.py +++ b/tests/unit/views/test_workers.py @@ -54,7 +54,7 @@ def test_single_workers_offline(self): self.assertEqual(200, r.code) self.assertEqual(1, len(table.rows())) self.assertTrue(table.get_row('worker1')) - self.assertEqual(['worker1', 'False', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker1', None, 'False', '0', '0', '0', '0', '0', None], table.get_row('worker1')) self.assertFalse(table.get_row('worker2')) @@ -81,8 +81,40 @@ def test_single_workers_online(self): state = EventsState() state.get_or_create_worker('worker1') state.event(Event('worker-online', hostname='worker1', - local_received=time.time())) + local_received=time.time(), + )) self.app.events.state = state + self.app.inspector.workers['worker1'] = {'registeres': [], + 'active_queues': [{ + 'name': 'default_queue', + 'exchange': { + 'name': 'default', + 'type': 'direct', + 'arguments': None, + 'durable': True, + 'passive': False, + 'auto_delete': False, + 'delivery_mode': None, + 'no_declare': False + }, + 'routing_key': 'default', + 'queue_arguments': None, + 'binding_arguments': None, + 'consumer_arguments': None, + 'durable': True, + 'exclusive': False, + 'auto_delete': False, + 'no_ack': False, + 'alias': None, + 'bindings': [], + 'no_declare': None, + 'expires': None, + 'message_ttl': None, + 'max_length': None, + 'max_length_bytes': None, + 'max_priority': None}], + 'stats': {'total': {'tasks.add': 10, 'tasks.sleep': 1, 'tasks.error': 1}, + 'broker': {'hostname': 'redis', 'userid': None, 'virtual_host': '/', 'port': 6379}}} r = self.get('/workers') @@ -92,7 +124,7 @@ def test_single_workers_online(self): self.assertEqual(200, r.code) self.assertEqual(1, len(table.rows())) self.assertTrue(table.get_row('worker1')) - self.assertEqual(['worker1', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker1', 'default_queue', 'True', '0', '0', '0', '0', '0', None], table.get_row('worker1')) self.assertFalse(table.get_row('worker2')) @@ -120,9 +152,9 @@ def test_task_received(self): self.assertEqual(200, r.code) self.assertEqual(2, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '1', '0', '0', '0', None], + self.assertEqual(['worker1', None, 'True', '0', '1', '0', '0', '0', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) def test_task_started(self): @@ -150,9 +182,9 @@ def test_task_started(self): self.assertEqual(200, r.code) self.assertEqual(2, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '1', '0', '0', '0', None], + self.assertEqual(['worker1', None, 'True', '0', '1', '0', '0', '0', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) def test_task_succeeded(self): @@ -182,9 +214,9 @@ def test_task_succeeded(self): self.assertEqual(200, r.code) self.assertEqual(2, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '1', '0', '1', '0', None], + self.assertEqual(['worker1', None, 'True', '0', '1', '0', '1', '0', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) def test_task_failed(self): @@ -214,9 +246,9 @@ def test_task_failed(self): self.assertEqual(200, r.code) self.assertEqual(2, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '1', '1', '0', '0', None], + self.assertEqual(['worker1', None, 'True', '0', '1', '1', '0', '0', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) def test_task_retried(self): @@ -248,9 +280,9 @@ def test_task_retried(self): self.assertEqual(200, r.code) self.assertEqual(2, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '1', '1', '0', '1', None], + self.assertEqual(['worker1', None, 'True', '0', '1', '1', '0', '1', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) def test_tasks(self): @@ -281,11 +313,11 @@ def test_tasks(self): self.assertEqual(200, r.code) self.assertEqual(3, len(table.rows())) - self.assertEqual(['worker1', 'True', '0', '100', '0', '100', '0', None], + self.assertEqual(['worker1', None, 'True', '0', '100', '0', '100', '0', None], table.get_row('worker1')) - self.assertEqual(['worker2', 'True', '0', '0', '0', '0', '0', None], + self.assertEqual(['worker2', None, 'True', '0', '0', '0', '0', '0', None], table.get_row('worker2')) - self.assertEqual(['worker3', 'True', '0', '23', '13', '10', '0', None], + self.assertEqual(['worker3', None, 'True', '0', '23', '13', '10', '0', None], table.get_row('worker3')) def test_workers_view_json(self):