tasq-client-python 0.1.17__py3-none-any.whl → 0.1.18__py3-none-any.whl

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/client.py CHANGED
@@ -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(self) -> Generator[Optional["RunningTask"], None, None]:
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
- self.client.completed(self.id)
417
+ fn(self.id)
418
+ self._sent_final_status = True
378
419
 
379
420
  @staticmethod
380
421
  def _keepalive_worker(
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.4
2
+ Name: tasq-client-python
3
+ Version: 0.1.18
4
+ Requires-Dist: requests
5
+ Dynamic: requires-dist
@@ -0,0 +1,8 @@
1
+ tasq_client/__init__.py,sha256=I0ik-_c0hcVKUgx7QsE3YnoCQyAVMFKKOzoLt-jNFtE,277
2
+ tasq_client/check_type.py,sha256=t_jreI8rf6QWS9Jf105ZvUVbwFe-uL4rMg4kZk6e4cA,2795
3
+ tasq_client/check_type_test.py,sha256=bvhVaO-Bu18aI3J4Kxnb0H27fzDCKkTHVBWhjJMFMis,1433
4
+ tasq_client/client.py,sha256=3og7zL7TkGmAYIDzt-fyrNfovvghiJL8Iy_TCsiad0w,16730
5
+ tasq_client_python-0.1.18.dist-info/METADATA,sha256=5w7-axKtRfNu28vjLIyRFGCG-r04ABxMBSnvGdtpZjU,110
6
+ tasq_client_python-0.1.18.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
+ tasq_client_python-0.1.18.dist-info/top_level.txt,sha256=JUs_FTRfs_ggMu8zusU5CSXgAl-JHhrjMXxuZay-B58,12
8
+ tasq_client_python-0.1.18.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.37.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: tasq-client-python
3
- Version: 0.1.17
4
- Summary: UNKNOWN
5
- Home-page: UNKNOWN
6
- License: UNKNOWN
7
- Platform: UNKNOWN
8
- Requires-Dist: requests
9
-
10
- UNKNOWN
11
-
@@ -1,8 +0,0 @@
1
- tasq_client/__init__.py,sha256=I0ik-_c0hcVKUgx7QsE3YnoCQyAVMFKKOzoLt-jNFtE,277
2
- tasq_client/check_type.py,sha256=t_jreI8rf6QWS9Jf105ZvUVbwFe-uL4rMg4kZk6e4cA,2795
3
- tasq_client/check_type_test.py,sha256=bvhVaO-Bu18aI3J4Kxnb0H27fzDCKkTHVBWhjJMFMis,1433
4
- tasq_client/client.py,sha256=Bn9koJj_pf3Iie6CmNXf_EY4An5Nduf5Ref4kY6zHkw,15332
5
- tasq_client_python-0.1.17.dist-info/METADATA,sha256=nrhAv0mDPEPzj0V-MpuJCC0omtI5E9hWHMspmaNoYBY,168
6
- tasq_client_python-0.1.17.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
7
- tasq_client_python-0.1.17.dist-info/top_level.txt,sha256=JUs_FTRfs_ggMu8zusU5CSXgAl-JHhrjMXxuZay-B58,12
8
- tasq_client_python-0.1.17.dist-info/RECORD,,