diff --git a/client/app/pages/queries/query.html b/client/app/pages/queries/query.html
index e4eff25bd2..f0050d0619 100644
--- a/client/app/pages/queries/query.html
+++ b/client/app/pages/queries/query.html
@@ -213,7 +213,7 @@
- Query in queue…
+ Query in queue (waiting on {{queryResult.job.queue_length}} queryies)…
diff --git a/redash/tasks/queries.py b/redash/tasks/queries.py
index abc967959b..8608c64101 100644
--- a/redash/tasks/queries.py
+++ b/redash/tasks/queries.py
@@ -181,12 +181,22 @@ def to_dict(self):
else:
query_result_id = None
+ queries_ahead = 0
+ if task_status == 'PENDING':
+ waiting = QueryTaskTracker.all(QueryTaskTracker.WAITING_LIST)
+ waiting_length = len(waiting)
+ # find our job's index, return number of queries after it
+ for i, waiting_task in enumerate(waiting):
+ if waiting_task.data['task_id'] == self._async_result.id:
+ queries_ahead = waiting_length - i - 1
+ break
return {
'id': self._async_result.id,
'updated_at': updated_at,
'status': status,
'error': error,
'query_result_id': query_result_id,
+ 'queue_length': queries_ahead,
}
@property
diff --git a/tests/handlers/test_query_results.py b/tests/handlers/test_query_results.py
index 1af3c1a3a5..0f69254715 100644
--- a/tests/handlers/test_query_results.py
+++ b/tests/handlers/test_query_results.py
@@ -1,8 +1,9 @@
+import mock
from tests import BaseTestCase
from redash.models import db
-from redash.utils import json_dumps
-
+from redash.tasks.queries import QueryTaskTracker
+from redash.utils import gen_query_hash, json_dumps
class TestQueryResultsCacheHeaders(BaseTestCase):
def test_uses_cache_headers_for_specific_result(self):
@@ -38,7 +39,6 @@ def test_get_existing_result(self):
self.assertEquals(query_result.id, rv.json['query_result']['id'])
def test_execute_new_query(self):
- query_result = self.factory.create_query_result()
query = self.factory.create_query()
rv = self.make_request('post', '/api/query_results',
@@ -50,6 +50,45 @@ def test_execute_new_query(self):
self.assertNotIn('query_result', rv.json)
self.assertIn('job', rv.json)
+ def test_queue_length(self):
+ query = self.factory.create_query()
+ tasks = []
+ def fake_all(*a, **kw):
+ return tasks
+ def enqueue_query(query, *a, **kw):
+ from redash.tasks.queries import enqueue_query
+ job = enqueue_query(query, *a, **kw)
+ tasks.append(QueryTaskTracker.create(
+ task_id=job.id,
+ state='waiting',
+ query_hash=gen_query_hash(query),
+ data_source_id=None,
+ scheduled=False,
+ metadata={}))
+ return job
+ patch_all = mock.patch('redash.tasks.queries.QueryTaskTracker.all',
+ classmethod(fake_all))
+ patch_enqueue_query = mock.patch('redash.handlers.query_results.enqueue_query',
+ enqueue_query)
+ with patch_all, patch_enqueue_query:
+ rv0 = self.make_request('post', '/api/query_results',
+ data={'data_source_id': self.factory.data_source.id,
+ 'query': query.query_text,
+ 'max_age': 0})
+ rv1 = self.make_request('post', '/api/query_results',
+ data={'data_source_id': self.factory.data_source.id,
+ 'query': query.query_text,
+ 'max_age': 0})
+ rv2 = self.make_request('post', '/api/query_results',
+ data={'data_source_id': self.factory.data_source.id,
+ 'query': query.query_text,
+ 'max_age': 0})
+
+ self.assertEquals(rv0.json['job']['queue_length'], 0)
+ self.assertEquals(rv1.json['job']['queue_length'], 1)
+ self.assertEquals(rv2.json['job']['queue_length'], 2)
+
+
def test_execute_query_without_access(self):
group = self.factory.create_group()
db.session.commit()