pydocket 0.3.2__py3-none-any.whl → 0.4.0__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.

Potentially problematic release.


This version of pydocket might be problematic. Click here for more details.

docket/docket.py CHANGED
@@ -132,6 +132,9 @@ class Docket:
132
132
  - "redis://user:password@localhost:6379/0?ssl=true"
133
133
  - "rediss://localhost:6379/0"
134
134
  - "unix:///path/to/redis.sock"
135
+ heartbeat_interval: How often workers send heartbeat messages to the docket.
136
+ missed_heartbeats: How many heartbeats a worker can miss before it is
137
+ considered dead.
135
138
  """
136
139
  self.name = name
137
140
  self.url = url
@@ -305,6 +308,9 @@ class Docket:
305
308
  def stream_key(self) -> str:
306
309
  return f"{self.name}:stream"
307
310
 
311
+ def known_task_key(self, key: str) -> str:
312
+ return f"{self.name}:known:{key}"
313
+
308
314
  def parked_task_key(self, key: str) -> str:
309
315
  return f"{self.name}:{key}"
310
316
 
@@ -340,30 +346,36 @@ class Docket:
340
346
  when = execution.when
341
347
 
342
348
  async with self.redis() as redis:
343
- # if the task is already in the queue, retain it
344
- if await redis.zscore(self.queue_key, key) is not None:
349
+ # if the task is already in the queue or stream, retain it
350
+ if await redis.exists(self.known_task_key(key)):
351
+ logger.debug(
352
+ "Task %r is already in the queue or stream, skipping schedule",
353
+ key,
354
+ extra=self.labels(),
355
+ )
345
356
  return
346
357
 
347
- if when <= datetime.now(timezone.utc):
348
- await redis.xadd(self.stream_key, message) # type: ignore[arg-type]
349
- else:
350
- async with redis.pipeline() as pipe:
358
+ async with redis.pipeline() as pipe:
359
+ pipe.set(self.known_task_key(key), when.timestamp())
360
+
361
+ if when <= datetime.now(timezone.utc):
362
+ pipe.xadd(self.stream_key, message) # type: ignore[arg-type]
363
+ else:
351
364
  pipe.hset(self.parked_task_key(key), mapping=message) # type: ignore[arg-type]
352
365
  pipe.zadd(self.queue_key, {key: when.timestamp()})
353
- await pipe.execute()
366
+
367
+ await pipe.execute()
354
368
 
355
369
  TASKS_SCHEDULED.add(1, {**self.labels(), **execution.general_labels()})
356
370
 
357
371
  async def cancel(self, key: str) -> None:
358
372
  with tracer.start_as_current_span(
359
373
  "docket.cancel",
360
- attributes={
361
- **self.labels(),
362
- "docket.key": key,
363
- },
374
+ attributes={**self.labels(), "docket.key": key},
364
375
  ):
365
376
  async with self.redis() as redis:
366
377
  async with redis.pipeline() as pipe:
378
+ pipe.delete(self.known_task_key(key))
367
379
  pipe.delete(self.parked_task_key(key))
368
380
  pipe.zrem(self.queue_key, key)
369
381
  await pipe.execute()
docket/worker.py CHANGED
@@ -377,6 +377,9 @@ class Worker:
377
377
 
378
378
  execution = Execution.from_message(function, message)
379
379
 
380
+ async with self.docket.redis() as redis:
381
+ await redis.delete(self.docket.known_task_key(execution.key))
382
+
380
383
  log_context = {**log_context, **execution.specific_labels()}
381
384
  counter_labels = {**self.labels(), **execution.general_labels()}
382
385
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydocket
3
- Version: 0.3.2
3
+ Version: 0.4.0
4
4
  Summary: A distributed background task system for Python functions
5
5
  Project-URL: Homepage, https://github.com/chrisguidry/docket
6
6
  Project-URL: Bug Tracker, https://github.com/chrisguidry/docket/issues
@@ -3,14 +3,14 @@ docket/__main__.py,sha256=Vkuh7aJ-Bl7QVpVbbkUksAd_hn05FiLmWbc-8kbhZQ4,34
3
3
  docket/annotations.py,sha256=GZwOPtPXyeIhnsLh3TQMBnXrjtTtSmF4Ratv4vjPx8U,950
4
4
  docket/cli.py,sha256=EseF0Sj7IEgd9QDC-FSbHSffvF7DNsrmDGYGgZBdJc8,19413
5
5
  docket/dependencies.py,sha256=S3KqXxEF0Q2t_jO3R-kI5IIA3M-tqybtiSod2xnRO4o,4991
6
- docket/docket.py,sha256=zva6ofTm7i5hRwAaAnNtlgIqoMPaNLqCTs2PXGka_8s,19723
6
+ docket/docket.py,sha256=xjmXZtE2QY6Pet5Gv5hEJNr8d5wp3zL1GJqRbJYwnKs,20321
7
7
  docket/execution.py,sha256=PDrlAr8VzmB6JvqKO71YhXUcTcGQW7eyXrSKiTcAexE,12508
8
8
  docket/instrumentation.py,sha256=bZlGA02JoJcY0J1WGm5_qXDfY0AXKr0ZLAYu67wkeKY,4611
9
9
  docket/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  docket/tasks.py,sha256=RIlSM2omh-YDwVnCz6M5MtmK8T_m_s1w2OlRRxDUs6A,1437
11
- docket/worker.py,sha256=MO-j5NQWvhlZh0vCVeUCwLas3i6AVsY672MYgyoU620,21882
12
- pydocket-0.3.2.dist-info/METADATA,sha256=F0cKpadZ6gQ-mJYXde7XTogoy_uaaTpprpJ5uum9z-w,13092
13
- pydocket-0.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
- pydocket-0.3.2.dist-info/entry_points.txt,sha256=4WOk1nUlBsUT5O3RyMci2ImuC5XFswuopElYcLHtD5k,47
15
- pydocket-0.3.2.dist-info/licenses/LICENSE,sha256=YuVWU_ZXO0K_k2FG8xWKe5RGxV24AhJKTvQmKfqXuyk,1087
16
- pydocket-0.3.2.dist-info/RECORD,,
11
+ docket/worker.py,sha256=3gyXOMaXTBAqEMJqTbItssWtil4ZtVT32UZZoaqWxK0,22006
12
+ pydocket-0.4.0.dist-info/METADATA,sha256=eZAK9MrnZBJhgH8Nc_JDWykcETUU5wszL0KbAPq8ha0,13092
13
+ pydocket-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
+ pydocket-0.4.0.dist-info/entry_points.txt,sha256=4WOk1nUlBsUT5O3RyMci2ImuC5XFswuopElYcLHtD5k,47
15
+ pydocket-0.4.0.dist-info/licenses/LICENSE,sha256=YuVWU_ZXO0K_k2FG8xWKe5RGxV24AhJKTvQmKfqXuyk,1087
16
+ pydocket-0.4.0.dist-info/RECORD,,