tasq-client-python 0.1.17__tar.gz → 0.1.18__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.
- tasq_client_python-0.1.18/PKG-INFO +5 -0
- tasq_client_python-0.1.18/pyproject.toml +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/setup.py +1 -1
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client/client.py +46 -5
- tasq_client_python-0.1.18/tasq_client_python.egg-info/PKG-INFO +5 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/SOURCES.txt +1 -0
- tasq-client-python-0.1.17/PKG-INFO +0 -10
- tasq-client-python-0.1.17/tasq_client_python.egg-info/PKG-INFO +0 -10
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/README.md +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/setup.cfg +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client/__init__.py +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client/check_type.py +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client/check_type_test.py +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/dependency_links.txt +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/requires.txt +0 -0
- {tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/top_level.txt +0 -0
|
File without changes
|
|
@@ -6,13 +6,15 @@ from contextlib import contextmanager
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from queue import Empty, Queue
|
|
8
8
|
from threading import Thread
|
|
9
|
-
from typing import Any, Dict, Generator, List, Optional, Tuple
|
|
9
|
+
from typing import Any, Callable, Dict, Generator, List, Literal, Optional, Tuple
|
|
10
10
|
|
|
11
11
|
import requests
|
|
12
12
|
from requests.adapters import HTTPAdapter, Retry
|
|
13
13
|
|
|
14
14
|
from .check_type import CheckTypeException, OptionalKey, OptionalValue, check_type
|
|
15
15
|
|
|
16
|
+
ExceptionBehavior = Literal["fail", "expire", "ignore"]
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
@dataclass
|
|
18
20
|
class Task:
|
|
@@ -31,6 +33,9 @@ class QueueCounts:
|
|
|
31
33
|
expired: int
|
|
32
34
|
completed: int
|
|
33
35
|
|
|
36
|
+
# This is a newer field, so legacy servers will not return it.
|
|
37
|
+
failed: int = 0
|
|
38
|
+
|
|
34
39
|
# Won't be set if a time window wasn't specified in the request, or if the
|
|
35
40
|
# server is old enough to not support rate estimation.
|
|
36
41
|
rate: Optional[float] = None
|
|
@@ -226,8 +231,18 @@ class TasqClient:
|
|
|
226
231
|
"""Reset the timeout interval for a still in-progress task."""
|
|
227
232
|
self._post_form("/task/keepalive", dict(id=id), supports_timeout=True)
|
|
228
233
|
|
|
234
|
+
def expire(self, id: str):
|
|
235
|
+
"""Mark the given task as expired."""
|
|
236
|
+
self._post_form("/task/expire", dict(id=id))
|
|
237
|
+
|
|
238
|
+
def failed(self, id: str):
|
|
239
|
+
"""Mark the given task as failed."""
|
|
240
|
+
self._post_form("/task/failed", dict(id=id))
|
|
241
|
+
|
|
229
242
|
@contextmanager
|
|
230
|
-
def pop_running_task(
|
|
243
|
+
def pop_running_task(
|
|
244
|
+
self, on_exception: ExceptionBehavior = "ignore"
|
|
245
|
+
) -> Generator[Optional["RunningTask"], None, None]:
|
|
231
246
|
"""
|
|
232
247
|
Pop a task from the queue and wrap it in a RunningTask, blocking until
|
|
233
248
|
the queue is completely empty or a task is successfully popped.
|
|
@@ -238,6 +253,11 @@ class TasqClient:
|
|
|
238
253
|
This is meant to be used in a `with` clause. When the `with` clause is
|
|
239
254
|
exited, the keepalive loop is stopped, and the task will be marked as
|
|
240
255
|
completed unless the with clause is exited with an exception.
|
|
256
|
+
|
|
257
|
+
In the case of an exception, the on_exception behavior determines what
|
|
258
|
+
is done with the task. Optionally, the task can be marked as expired or
|
|
259
|
+
failed; by default, the task will be left in the running state until
|
|
260
|
+
its timeout expires.
|
|
241
261
|
"""
|
|
242
262
|
while True:
|
|
243
263
|
task, timeout = self.pop()
|
|
@@ -245,9 +265,16 @@ class TasqClient:
|
|
|
245
265
|
rt = RunningTask(self, id=task.id, contents=task.contents)
|
|
246
266
|
try:
|
|
247
267
|
yield rt
|
|
268
|
+
except:
|
|
269
|
+
if on_exception == "fail":
|
|
270
|
+
rt.failed()
|
|
271
|
+
elif on_exception == "expire":
|
|
272
|
+
rt.expire()
|
|
273
|
+
else:
|
|
274
|
+
rt.cancel()
|
|
275
|
+
raise
|
|
276
|
+
else:
|
|
248
277
|
rt.completed()
|
|
249
|
-
finally:
|
|
250
|
-
rt.cancel()
|
|
251
278
|
return
|
|
252
279
|
elif timeout is not None:
|
|
253
280
|
time.sleep(min(timeout, self.max_timeout))
|
|
@@ -264,6 +291,7 @@ class TasqClient:
|
|
|
264
291
|
"running": int,
|
|
265
292
|
"expired": int,
|
|
266
293
|
"completed": int,
|
|
294
|
+
OptionalKey("failed"): int,
|
|
267
295
|
OptionalKey("minute_rate"): float,
|
|
268
296
|
OptionalKey("modtime"): int,
|
|
269
297
|
OptionalKey("bytes"): int,
|
|
@@ -364,6 +392,7 @@ class RunningTask(Task):
|
|
|
364
392
|
daemon=True,
|
|
365
393
|
)
|
|
366
394
|
self._thread.start()
|
|
395
|
+
self._sent_final_status = False
|
|
367
396
|
|
|
368
397
|
def cancel(self):
|
|
369
398
|
if self._thread is None:
|
|
@@ -373,8 +402,20 @@ class RunningTask(Task):
|
|
|
373
402
|
self._thread = None
|
|
374
403
|
|
|
375
404
|
def completed(self):
|
|
405
|
+
self._send_status(self.client.completed)
|
|
406
|
+
|
|
407
|
+
def failed(self):
|
|
408
|
+
self._send_status(self.client.failed)
|
|
409
|
+
|
|
410
|
+
def expire(self):
|
|
411
|
+
self._send_status(self.client.expire)
|
|
412
|
+
|
|
413
|
+
def _send_status(self, fn: Callable[[str], None]):
|
|
414
|
+
if self._sent_final_status:
|
|
415
|
+
return
|
|
376
416
|
self.cancel()
|
|
377
|
-
|
|
417
|
+
fn(self.id)
|
|
418
|
+
self._sent_final_status = True
|
|
378
419
|
|
|
379
420
|
@staticmethod
|
|
380
421
|
def _keepalive_worker(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{tasq-client-python-0.1.17 → tasq_client_python-0.1.18}/tasq_client_python.egg-info/top_level.txt
RENAMED
|
File without changes
|