tasktiger 0.26.3__tar.gz → 0.27.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tasktiger-0.26.3/tasktiger.egg-info → tasktiger-0.27.0}/PKG-INFO +13 -1
- {tasktiger-0.26.3 → tasktiger-0.27.0}/README.rst +12 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/__init__.py +1 -1
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/stats.py +12 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/worker.py +9 -3
- {tasktiger-0.26.3 → tasktiger-0.27.0/tasktiger.egg-info}/PKG-INFO +13 -1
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_workers.py +37 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/LICENSE +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/MANIFEST.in +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/pyproject.toml +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/setup.cfg +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/setup.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/_internal.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/exceptions.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/executor.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/flask_script.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/logging.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/lua/move_task.lua +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/lua/semaphore.lua +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/migrations.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/redis_scripts.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/redis_semaphore.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/retry.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/rollbar.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/runner.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/schedule.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/task.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/tasktiger.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/test_helpers.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/timeouts.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/types.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger/utils.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger.egg-info/SOURCES.txt +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger.egg-info/dependency_links.txt +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger.egg-info/entry_points.txt +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger.egg-info/requires.txt +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tasktiger.egg-info/top_level.txt +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/__init__.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/config.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/conftest.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/tasks.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/tasks_periodic.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_base.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_context_manager.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_lazy_init.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_logging.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_migrations.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_periodic.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_queue_size.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_redis_scripts.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_semaphore.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_stats.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/test_task.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tests/utils.py +0 -0
- {tasktiger-0.26.3 → tasktiger-0.27.0}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tasktiger
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: Python task queue
|
|
5
5
|
Home-page: http://github.com/closeio/tasktiger
|
|
6
6
|
License: MIT
|
|
@@ -212,6 +212,18 @@ decorate and queue tasks. The constructor takes the following arguments:
|
|
|
212
212
|
given queues (and their subqueues), unless explicit queues are passed to
|
|
213
213
|
the command line.
|
|
214
214
|
|
|
215
|
+
- ``STATS_INTERVAL``
|
|
216
|
+
|
|
217
|
+
Interval in seconds between worker task runtime statistics (default: 60).
|
|
218
|
+
Set to 0 to disable the stats thread and its callbacks. Queue maintenance
|
|
219
|
+
can occupy a worker outside task-execution statistics. When enabled,
|
|
220
|
+
``StatsThread.report_maintenance_start()`` and ``report_maintenance_end()``
|
|
221
|
+
bracket the combined scheduled-task promotion and expired-task recovery
|
|
222
|
+
pass, with the end callback called even if either operation raises.
|
|
223
|
+
The hooks allow custom instrumentation; their defaults are no-ops and do
|
|
224
|
+
not change task runtime or utilization statistics. No maintenance callbacks
|
|
225
|
+
run when maintenance is not due or the worker is stopping.
|
|
226
|
+
|
|
215
227
|
- ``setup_structlog``
|
|
216
228
|
|
|
217
229
|
If set to True, sets up structured logging using ``structlog`` when
|
|
@@ -182,6 +182,18 @@ decorate and queue tasks. The constructor takes the following arguments:
|
|
|
182
182
|
given queues (and their subqueues), unless explicit queues are passed to
|
|
183
183
|
the command line.
|
|
184
184
|
|
|
185
|
+
- ``STATS_INTERVAL``
|
|
186
|
+
|
|
187
|
+
Interval in seconds between worker task runtime statistics (default: 60).
|
|
188
|
+
Set to 0 to disable the stats thread and its callbacks. Queue maintenance
|
|
189
|
+
can occupy a worker outside task-execution statistics. When enabled,
|
|
190
|
+
``StatsThread.report_maintenance_start()`` and ``report_maintenance_end()``
|
|
191
|
+
bracket the combined scheduled-task promotion and expired-task recovery
|
|
192
|
+
pass, with the end callback called even if either operation raises.
|
|
193
|
+
The hooks allow custom instrumentation; their defaults are no-ops and do
|
|
194
|
+
not change task runtime or utilization statistics. No maintenance callbacks
|
|
195
|
+
run when maintenance is not due or the worker is stopping.
|
|
196
|
+
|
|
185
197
|
- ``setup_structlog``
|
|
186
198
|
|
|
187
199
|
If set to True, sets up structured logging using ``structlog`` when
|
|
@@ -39,6 +39,18 @@ class StatsThread(threading.Thread):
|
|
|
39
39
|
self._task_running = False
|
|
40
40
|
self._task_start_time = None
|
|
41
41
|
|
|
42
|
+
def report_maintenance_start(self) -> None:
|
|
43
|
+
"""Signal the start of scheduled-task promotion and expired-task recovery.
|
|
44
|
+
|
|
45
|
+
The default is a no-op and does not alter task statistics.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def report_maintenance_end(self) -> None:
|
|
49
|
+
"""Signal the end of scheduled-task promotion and expired-task recovery.
|
|
50
|
+
|
|
51
|
+
The default is a no-op and does not alter task statistics.
|
|
52
|
+
"""
|
|
53
|
+
|
|
42
54
|
def compute_stats(self) -> None:
|
|
43
55
|
now = time.monotonic()
|
|
44
56
|
|
|
@@ -867,9 +867,15 @@ class Worker:
|
|
|
867
867
|
time.time() - self._last_task_check > self.config["SELECT_TIMEOUT"]
|
|
868
868
|
and not self._stop_requested
|
|
869
869
|
):
|
|
870
|
-
self.
|
|
871
|
-
|
|
872
|
-
|
|
870
|
+
if self.stats_thread:
|
|
871
|
+
self.stats_thread.report_maintenance_start()
|
|
872
|
+
try:
|
|
873
|
+
self._worker_queue_scheduled_tasks()
|
|
874
|
+
self._worker_queue_expired_tasks()
|
|
875
|
+
self._last_task_check = time.time()
|
|
876
|
+
finally:
|
|
877
|
+
if self.stats_thread:
|
|
878
|
+
self.stats_thread.report_maintenance_end()
|
|
873
879
|
|
|
874
880
|
def _queue_periodic_tasks(self) -> None:
|
|
875
881
|
# Only queue periodic tasks for queues this worker is responsible
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tasktiger
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: Python task queue
|
|
5
5
|
Home-page: http://github.com/closeio/tasktiger
|
|
6
6
|
License: MIT
|
|
@@ -212,6 +212,18 @@ decorate and queue tasks. The constructor takes the following arguments:
|
|
|
212
212
|
given queues (and their subqueues), unless explicit queues are passed to
|
|
213
213
|
the command line.
|
|
214
214
|
|
|
215
|
+
- ``STATS_INTERVAL``
|
|
216
|
+
|
|
217
|
+
Interval in seconds between worker task runtime statistics (default: 60).
|
|
218
|
+
Set to 0 to disable the stats thread and its callbacks. Queue maintenance
|
|
219
|
+
can occupy a worker outside task-execution statistics. When enabled,
|
|
220
|
+
``StatsThread.report_maintenance_start()`` and ``report_maintenance_end()``
|
|
221
|
+
bracket the combined scheduled-task promotion and expired-task recovery
|
|
222
|
+
pass, with the end callback called even if either operation raises.
|
|
223
|
+
The hooks allow custom instrumentation; their defaults are no-ops and do
|
|
224
|
+
not change task runtime or utilization statistics. No maintenance callbacks
|
|
225
|
+
run when maintenance is not due or the worker is stopping.
|
|
226
|
+
|
|
215
227
|
- ``setup_structlog``
|
|
216
228
|
|
|
217
229
|
If set to True, sets up structured logging using ``structlog`` when
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
import datetime
|
|
4
4
|
import time
|
|
5
5
|
from multiprocessing import Process
|
|
6
|
+
from unittest import mock
|
|
6
7
|
|
|
8
|
+
import pytest
|
|
7
9
|
from freezefrog import FreezeTime
|
|
8
10
|
|
|
9
11
|
from tasktiger import Task, Worker
|
|
10
12
|
from tasktiger._internal import ACTIVE
|
|
11
13
|
from tasktiger.executor import SyncExecutor
|
|
14
|
+
from tasktiger.stats import StatsThread
|
|
12
15
|
from tasktiger.worker import LOCK_REDIS_KEY
|
|
13
16
|
|
|
14
17
|
from .config import DELAY
|
|
@@ -265,3 +268,37 @@ class TestSyncExecutorWorker:
|
|
|
265
268
|
# handled by the executor, the task is still active until it times out
|
|
266
269
|
# and gets requeued by another worker.
|
|
267
270
|
ensure_queues(active={"default": 1})
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@pytest.mark.parametrize("failing_operation", [None, "scheduled", "expired"])
|
|
274
|
+
def test_maintenance_stats_callbacks(tiger, monkeypatch, failing_operation):
|
|
275
|
+
worker = Worker(tiger)
|
|
276
|
+
worker._queue_set = set()
|
|
277
|
+
calls = mock.Mock()
|
|
278
|
+
calls.stats = mock.Mock(spec=StatsThread)
|
|
279
|
+
worker.stats_thread = calls.stats
|
|
280
|
+
monkeypatch.setattr(worker, "_worker_queue_scheduled_tasks", calls.scheduled)
|
|
281
|
+
monkeypatch.setattr(worker, "_worker_queue_expired_tasks", calls.expired)
|
|
282
|
+
|
|
283
|
+
if failing_operation:
|
|
284
|
+
getattr(calls, failing_operation).side_effect = RuntimeError("maintenance")
|
|
285
|
+
with pytest.raises(RuntimeError, match="maintenance"):
|
|
286
|
+
worker._worker_run()
|
|
287
|
+
else:
|
|
288
|
+
worker._worker_run()
|
|
289
|
+
|
|
290
|
+
expected = [mock.call.stats.report_maintenance_start(), mock.call.scheduled()]
|
|
291
|
+
if failing_operation != "scheduled":
|
|
292
|
+
expected.append(mock.call.expired())
|
|
293
|
+
expected.append(mock.call.stats.report_maintenance_end())
|
|
294
|
+
assert calls.mock_calls == expected
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def test_maintenance_without_stats(tiger, monkeypatch):
|
|
298
|
+
worker = Worker(tiger)
|
|
299
|
+
worker._queue_set = set()
|
|
300
|
+
calls = mock.Mock()
|
|
301
|
+
monkeypatch.setattr(worker, "_worker_queue_scheduled_tasks", calls.scheduled)
|
|
302
|
+
monkeypatch.setattr(worker, "_worker_queue_expired_tasks", calls.expired)
|
|
303
|
+
worker._worker_run()
|
|
304
|
+
assert calls.mock_calls == [mock.call.scheduled(), mock.call.expired()]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|