ringo-task-queue 0.1.0.dev7__py3-none-win_amd64.whl → 0.1.0.dev8__py3-none-win_amd64.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ringo-task-queue
3
- Version: 0.1.0.dev7
3
+ Version: 0.1.0.dev8
4
4
  Summary: Python asyncio SDK for Ringo Task Queue with a bundled offline Go daemon
5
5
  Author: Ringo Task Queue contributors
6
6
  License-Expression: MIT
@@ -33,6 +33,8 @@ Requires-Dist: pytest>=8; extra == 'dev'
33
33
  Requires-Dist: ruff<1,>=0.11; extra == 'dev'
34
34
  Provides-Extra: generate
35
35
  Requires-Dist: grpcio-tools==1.71.0; extra == 'generate'
36
+ Provides-Extra: supervisor
37
+ Requires-Dist: psutil<8,>=7; (sys_platform != 'win32') and extra == 'supervisor'
36
38
  Provides-Extra: test
37
39
  Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
38
40
  Requires-Dist: pytest>=8; extra == 'test'
@@ -42,25 +44,27 @@ Description-Content-Type: text/markdown
42
44
 
43
45
  面向 Python 3.11+ 的 asyncio 任务队列 SDK。它支持 SDK 管理的本地 SQLite/PostgreSQL daemon 和远程 gRPC 服务,提供永久去重、至少一次执行、lease fencing、自动续租、重试和 DEAD/DLQ 语义。
44
46
 
47
+ **本文对应发行线:** Python `0.1.0.dev8` / Go `0.1.0-dev.8`,协议 **1.7 / Schema 3**。本文描述该版本代码与 wheel 的能力;是否已经公开上传,以 [PyPI 版本页](https://pypi.org/project/ringo-task-queue/0.1.0.dev8/) 和官方文件为准,候选构建本身不是发布证明。历史 dev7 使用协议 1.5,不包含 supervisor API。仅 Go 数据面与 Python SDK 持续维护;Node.js / Kotlin SDK 封存,保留历史代码/文档/测试,不维护、不发布,恢复须用户明确确认。
48
+
45
49
  ## 安装后即可离线运行
46
50
 
47
51
  ```shell
48
- pip install ringo-task-queue
52
+ python -m pip install --pre "ringo-task-queue==0.1.0.dev8"
49
53
  ```
50
54
 
51
- 正式发布包含五个同版本平台 wheel:
55
+ 平台 wheel 各内置对应 daemon;以下是分发目标,**不等于全部平台已完成原生运行验收**:
52
56
 
53
57
  | 系统 | wheel tag | 内置 daemon |
54
58
  |---|---|---|
55
59
  | Windows x64 | `win_amd64` | Windows x64 |
56
60
  | Linux x64 | `manylinux_2_17_x86_64` | Linux x64 |
57
61
  | Linux ARM64 | `manylinux_2_17_aarch64` | Linux ARM64 |
58
- | macOS Intel | `macosx_11_0_x86_64` | macOS Intel |
59
- | macOS Apple Silicon | `macosx_11_0_arm64` | macOS ARM64 |
62
+ | macOS 13+ Intel | `macosx_13_0_x86_64` | macOS 13+ Intel |
63
+ | macOS 13+ Apple Silicon | `macosx_13_0_arm64` | macOS 13+ ARM64 |
60
64
 
61
65
  `pip` 会自动选择当前平台的 wheel。每个 wheel 已包含匹配的 Go daemon;本地模式不会在安装或运行时下载二进制,不要求安装 Go,也不需要设置 `RINGO_DAEMON_PATH`。PostgreSQL 服务本身不包含在包内。
62
66
 
63
- 开发版本需要允许预发布:
67
+ 选择官方索引中实际存在的最新开发版本,需要允许预发布:
64
68
 
65
69
  ```shell
66
70
  pip install --pre ringo-task-queue
@@ -170,6 +174,8 @@ async with Ringo.connect(
170
174
 
171
175
  `compression` 只接受 `"none"` 或 `"gzip"`。它覆盖 unary RPC 和 Work stream 并在重连后保持;本地模式始终不压缩。
172
176
 
177
+ 协议 1.6 的 ordered Work sources / SQLite ACK group commit 是当前源码的历史演进边界,1.7 的只读 `ProbeQueue` 用于可选疑似停滞观察;都不是已发布 dev7 / 协议 1.5 能力。远端可以按契约降级,bundled/shared-local 的本地 SDK/daemon 仍须精确匹配版本、协议和 schema,不能因 Schema 相同就混装。
178
+
173
179
  ## 提交任务
174
180
 
175
181
  ```python
@@ -460,6 +466,86 @@ finally:
460
466
 
461
467
  本地 daemon 意外退出时最多自动重启三次。结果不确定的写操作不会被盲目重放;只读查询可以在重新协商后重试。
462
468
 
469
+ ## 可选业务进程守护(dev8)
470
+
471
+ 这是显式 opt-in API,不是 `Ringo.local()` 的自动重启选项,也不是通用服务平台。该 API 需要 dev8 或后续支持版本;历史 dev7 不提供。可从完整候选 wheel 集合验收,公开安装是否可用以官方 PyPI 文件为准:
472
+
473
+ ```shell
474
+ python -m pip install --pre 'ringo-task-queue[supervisor]==0.1.0.dev8'
475
+ ```
476
+
477
+ POSIX supervisor extra 安装 `psutil>=7,<8` 以观察进程身份/RSS;Windows 使用 native Job/进程 API,不强制 psutil。普通 Worker 不必启用 supervisor。源码 checkout 可自行安装 `.[supervisor]` extra 并准备同线 daemon,但源码/交叉构建不等于发行或全平台原生验证。
478
+
479
+ ### 一个同步启动器、两个不可变配置对象
480
+
481
+ ```python
482
+ from ringo_task_queue.supervisor import supervise, SupervisorPolicy, TaskTimeouts
483
+ # supervise(entrypoint: str, *, policy: SupervisorPolicy | None = None,
484
+ # task_timeouts: TaskTimeouts | None = None) -> int
485
+ ```
486
+
487
+ `supervise` 是 **blocking、main-thread** 启动器,必须在运行中的 asyncio loop 之外调用。入口是可导入、可零参调用的 `module:function`,支持 sync/async;同步入口可以自行拥有 `asyncio.run()`,异步入口的 awaitable 也可直接运行。不重建当前命令、不 pickle 闭包,不接受 `__main__` / 局部函数,也不递归监督自己。`SupervisorPolicy` / `TaskTimeouts` 是 immutable 配置,`by_type` 会复制成只读映射;所有公开时长使用 `datetime.timedelta`。
488
+
489
+ 真实 handler 可能健康运行 20–30 分钟时,要**同时**留够业务总预算、Worker drain 和父级整代 shutdown 三个窗口。以下 45/45/46 分钟仅为清楚的配置示例,不是通用 SLA;快任务应另配更短预算。
490
+
491
+ ```python
492
+ # myapp.py:可导入的零参业务入口,不在导入时启动事件循环
493
+ from datetime import timedelta as td
494
+ from ringo_task_queue import Ringo
495
+
496
+ async def main() -> None:
497
+ async with Ringo.local("./data/ringo") as client:
498
+ async def handle(task, ctx) -> None:
499
+ # 替换成幂等的异步业务;实际阶段完成后才 mark_progress。
500
+ print(task.id, task.payload)
501
+ ctx.mark_progress()
502
+
503
+ worker = client.queue("crawl").worker(
504
+ handle, task_types=["fetch-page"], concurrency=4,
505
+ grace_period=td(minutes=45),
506
+ task_timeouts=None, # 继承 launcher 的 TaskTimeouts
507
+ )
508
+ await worker.run()
509
+ ```
510
+
511
+ ```python
512
+ # launch.py:python launch.py,在最外层保护中同步调用,不放进 asyncio.run
513
+ from datetime import timedelta as td
514
+ from ringo_task_queue.supervisor import supervise, SupervisorPolicy, TaskTimeouts
515
+
516
+ if __name__ == "__main__":
517
+ raise SystemExit(supervise(
518
+ "myapp:main",
519
+ policy=SupervisorPolicy(
520
+ recycle_after=td(hours=12),
521
+ shutdown_grace=td(minutes=46),
522
+ no_start_timeout=td(minutes=5),
523
+ restart_on_stall=False,
524
+ ),
525
+ task_timeouts=TaskTimeouts(
526
+ default=td(minutes=45),
527
+ by_type={"fast": td(minutes=2), "unbounded": None},
528
+ progress_timeout=None,
529
+ cancel_grace=td(seconds=5),
530
+ ),
531
+ ))
532
+ ```
533
+
534
+ ### 总时长、业务进度和外层守护分开
535
+
536
+ - `TaskTimeouts.default` 是**实际业务执行总预算**,不含本地排队、permit 等待或业务结束后的 ACK/NACK 回执;`by_type` 只覆盖总预算,某类型的 `None` 表示该类型总时长 unlimited,不禁用独立的进度预算。
537
+ - `progress_timeout` 仅在首次真实业务进度后计时。`ctx.mark_progress()` 同步、本地、无 RPC,在 Worker 所属 asyncio 循环调用;业务线程可通过 `loop.call_soon_threadsafe(ctx.mark_progress)` 回送标记。`await ctx.report_progress(...)` 也记本地进度。从未报进度不判死;lease 续租、ACK 和其他 Worker 的推进都不是本任务的业务进度。按实际阶段推进标记,不为喂 watchdog 增加逐任务网络调用。
538
+ - `queue.worker(..., task_timeouts=None)` 继承 supervisor;传 `TaskTimeouts(...)` **整体替换而不合并**,包括 `by_type`、`progress_timeout` 与 `cancel_grace`。`TaskTimeouts()` 明确使该 Worker 不限任务总时长、不开进度超时。
539
+ - `startup_timeout` 只管启动/导入/就绪,`heartbeat_timeout` 管可响应性,`soft_rss_bytes` / `max_rss_bytes` 管 owned 树采样 RSS;**它们不是 task timeout**。默认可选破坏性阈值为 `None`,RSS 不是内核硬限额。硬 RSS 观察在整代 drain 期间仍生效;排空中越限会缩短等待并回收,原计划轮换也按资源故障计入重启预算。纯同步阻塞也会妨碍 asyncio 续租;WebDriver 等阻塞调用应使用异步方式或 `asyncio.to_thread`,而非依靠守护假装续租安全。
540
+ - 超时先 fence 再取消;协作停止且 lease/source 仍有效时可用超时错误 NACK。吞取消、`uncancel()` 或超时后返回都不能 ACK 成功。不配合且超过 `cancel_grace` 才请求整代恢复;单独 Worker 只能协作取消,不能强杀 Python/native/browser 代码。父级观察也是采样,不是实时硬截止;含 unlimited 类型时不能臆造通用总时长界限,需要另行选择独立心跳 SLA。
541
+ - `no_start_timeout` 启用协议 1.7 的只读 `ProbeQueue`,只查匹配 READY / 到期 SCHEDULED 且剩余 attempt 的 EXISTS,不 claim/reap/count 历史。它按每 Worker/当前 source、实际获 permit 与服务端 accepted credit 判断**疑似停滞**,默认 warn。`restart_on_stall=True` 显式接受多消费者竞争误判风险;远端 minor <7 跳过此探测但保留其他守护,不绕过正常版本握手。
542
+
543
+ ### 资源归属、退出与恢复
544
+
545
+ Windows 的 root 进程先以 **initially suspended** 状态创建,再 assign 到 native kill-on-close Job 后 resume,避免 venv redirector 在归属前派生 base interpreter;用户模块导入也等待 containment。shared-local daemon 使用显式 breakaway,失败不回退。POSIX 使用进程组/session 与身份跟踪,不是 cgroup,未被观察到就 setsid 逃逸的子进程不保证回收。共享 daemon、外部 PostgreSQL、远程 WebDriver 不归 business 所有;远端浏览器资源仍需业务 `try/finally` 或上下文清理。身份不明/清理不确定时 fail closed,不启动新代。
546
+
547
+ `shutdown_grace` 是**整代上限**,不是多个 Worker grace 相加;STOP 后所有 Worker 并行 drain。正常 return / exit 0 结束守护;计划轮换已触发时,即使收尾 exit 0 仍重启,且不消耗、不清空故障预算。Ctrl+C 停止而不重启。未确认任务按 lease expiry 恢复,已消耗 attempt 不退款、`maxAttempts` 耗尽进入 DEAD,不伪造成功或自动激活 DEAD,业务必须幂等。supervisor 自身/机器退出后的自动恢复属于 OS 外层服务管理,不由这个 API 承诺。
548
+
463
549
  ## 错误处理
464
550
 
465
551
  ```python
@@ -496,11 +582,14 @@ except RingoError as exc:
496
582
 
497
583
  | 项目 | 默认值或限制 |
498
584
  |---|---|
499
- | 协议 | 1.5 |
585
+ | 本发行线协议 | 1.7(历史 dev7 为 1.5) |
500
586
  | schema | 3 |
501
587
  | lease | 60 秒 |
502
588
  | worker concurrency | 1 |
503
- | graceful shutdown | 30 秒 |
589
+ | Worker graceful shutdown | 30 秒;长任务显式配置 `grace_period` |
590
+ | supervisor task total/progress timeout | 默认均为 `None`,不开任务预算 |
591
+ | supervisor shutdown/startup | 分别默认 30 秒;整代 shutdown 与任务总预算独立 |
592
+ | supervisor stall action | 默认 `restart_on_stall=False`;仅配置 no-start 窗口后观察并 warn |
504
593
  | retry attempts | 每轮默认 3,最大 32;累计历史不设生命周期 32 条上限 |
505
594
  | Task attempt 预览 | 最多 32 条 / 512 KiB,截断明确标记 |
506
595
  | 完整历史分页 | 默认 32,最多 100 条 / 1 MiB,需要协议 1.5 |
@@ -542,7 +631,7 @@ except RingoError as exc:
542
631
 
543
632
  ### Worker 关闭较慢
544
633
 
545
- 默认允许 handler 在 30 秒内完成。可以调整 `grace_period`,并让 handler 响应 cancellation 或 `ctx.cancelled`。
634
+ 默认允许 handler 在 30 秒内完成。可以调整 `grace_period`,并让 handler 响应 cancellation 或 `ctx.cancelled`。dev8 源码启用 supervisor 时还必须相应延长整代 `SupervisorPolicy.shutdown_grace`;例如健康 20–30 分钟任务可分别配置任务总预算 45 分钟、Worker grace 45 分钟、父级 shutdown 46 分钟。单独延长任务预算不会延长退出窗口。
546
635
 
547
636
  ## 许可证
548
637
 
@@ -0,0 +1,27 @@
1
+ ringo_task_queue/__init__.py,sha256=alSfOYp1QTH4eolTnSkl_gJpI-XC5LN7ijkoHQD4HZk,1571
2
+ ringo_task_queue/_pb.py,sha256=gA8HMCx9ZXEMB-ca6me8CYXdRLLPzUXVIz63Q4bz75I,5683
3
+ ringo_task_queue/_supervisor_child.py,sha256=yodTiYJ4UKRisYssVpxJvyamUt4M2eS1Hdp3EYOMngk,3155
4
+ ringo_task_queue/_supervisor_ipc.py,sha256=wZS3iHtB41QO7o70mEb8PsPfcVH07p-MEiy3K8c3Ug4,3110
5
+ ringo_task_queue/_supervisor_policy.py,sha256=moMF_khQDWajEOyNZ6fKNJCVWhyUF5JbhsvKbIw69jk,7375
6
+ ringo_task_queue/_supervisor_process.py,sha256=IBqNW0U6Dvt1tPCkgDSpmSam3kuVxft18D0P0OiroZA,23548
7
+ ringo_task_queue/_supervisor_runtime.py,sha256=N8FR5xCJ2bHrDcHf2td_x3-IysJzDChew6WxztgFWlo,16518
8
+ ringo_task_queue/_supervisor_watchdog.py,sha256=-gam4zvr98Ug1Dv59AMv1o2msiccJUT2R22FXIouSP8,17600
9
+ ringo_task_queue/_version.py,sha256=WtWgo4TJhfWDKq712U4ydYQ9SsH_EnzYYFD9cdFterA,642
10
+ ringo_task_queue/binary.py,sha256=lJtFz_t5BuxDV4dMAqQDpP3mhTvJlnPBGnaiB0Z9D04,9526
11
+ ringo_task_queue/client.py,sha256=G1q8BFgU-1_ZHoAJlvV4ypaJfAOFURwEqSg5Ig6IVP8,52084
12
+ ringo_task_queue/concurrency.py,sha256=AxmtDa39xoda0TnvxNlLmZri1TTWCkS7VaRomAONwLU,19151
13
+ ringo_task_queue/daemon.py,sha256=YS8otZpD9hqKeASb2S8ZWLCWzQj6-FYUb-grmYSnrIs,19849
14
+ ringo_task_queue/errors.py,sha256=FQXkfz0SS-mFtY61b6f9HamPZUPWcuf-33AfB7B0rmo,4829
15
+ ringo_task_queue/models.py,sha256=75hAR0XDAb0BFWvVaoBzj_HGrcIQX4MH6MFmJOHZENY,14556
16
+ ringo_task_queue/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ ringo_task_queue/shared.py,sha256=s2WB-6NKGxUoioOz3oGKazkdQBKuiSWvQzQyq_ABi-s,14105
18
+ ringo_task_queue/supervisor.py,sha256=ILc5hXwHSDjNjwdDFEL5RePsS9rUsjqWu_FzU8TU3ps,22559
19
+ ringo_task_queue/worker.py,sha256=p9rrFXU3k4np0m1Tio5XZx8ipLKVjSiM5hS_6rF_WsI,80397
20
+ ringo_task_queue/_proto/ringo/v1/queue_pb2.py,sha256=NehLqhJKBIakaeP0534UHOtZVnuWudMw2xN05bQZKfI,21867
21
+ ringo_task_queue/_proto/ringo/v1/queue_pb2_grpc.py,sha256=Nk_Eg1YV-LC7K4JV-KomgIaEx7hb5ZZ65V0bFg-XYyI,36822
22
+ ringo_task_queue/bin/manifest.json,sha256=WB1_K8ekW1bZiN8xk8pcMCy8CyUoVbiZQquIGEZjXls,680
23
+ ringo_task_queue/bin/ringo-task-queue-windows-amd64.exe,sha256=8zg_XS0jwjSq4CxyJ7OIsETuqwRxYcKedDno2GVFHFk,23455744
24
+ ringo_task_queue-0.1.0.dev8.dist-info/METADATA,sha256=UWL6dZEXJMQwjFkGCiB_XnkXFcoEQ9zdxEfu85Od7V8,28949
25
+ ringo_task_queue-0.1.0.dev8.dist-info/WHEEL,sha256=A7YmR1UrJozxyeLCzQFwQUdR7CRUwkFKasEDmnrjVxY,94
26
+ ringo_task_queue-0.1.0.dev8.dist-info/licenses/LICENSE,sha256=yK3nnJz_bbOAPlcJqAooYcvecNJnBH9miT_X8Qrerv4,1086
27
+ ringo_task_queue-0.1.0.dev8.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- ringo_task_queue/__init__.py,sha256=alSfOYp1QTH4eolTnSkl_gJpI-XC5LN7ijkoHQD4HZk,1571
2
- ringo_task_queue/_pb.py,sha256=gA8HMCx9ZXEMB-ca6me8CYXdRLLPzUXVIz63Q4bz75I,5683
3
- ringo_task_queue/_version.py,sha256=ELp1Vn-nind564WaXj4fMHfXlmae1xLCrzY_NziqvRw,642
4
- ringo_task_queue/binary.py,sha256=lJtFz_t5BuxDV4dMAqQDpP3mhTvJlnPBGnaiB0Z9D04,9526
5
- ringo_task_queue/client.py,sha256=sTt5BWDhLnvc0Oa0ocX7FIctVIRxWmvu9MBzSsY5QUI,49545
6
- ringo_task_queue/concurrency.py,sha256=AxmtDa39xoda0TnvxNlLmZri1TTWCkS7VaRomAONwLU,19151
7
- ringo_task_queue/daemon.py,sha256=YS8otZpD9hqKeASb2S8ZWLCWzQj6-FYUb-grmYSnrIs,19849
8
- ringo_task_queue/errors.py,sha256=FQXkfz0SS-mFtY61b6f9HamPZUPWcuf-33AfB7B0rmo,4829
9
- ringo_task_queue/models.py,sha256=75hAR0XDAb0BFWvVaoBzj_HGrcIQX4MH6MFmJOHZENY,14556
10
- ringo_task_queue/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- ringo_task_queue/shared.py,sha256=4XZxX6c7ZgdjwrBDzyZwFcNSbiRGa3lfQR54rPvXfZs,12179
12
- ringo_task_queue/worker.py,sha256=EyUXJ861WHJj3dlbkn45SCuLItofbdXoPo8VyWzrTFY,64321
13
- ringo_task_queue/_proto/ringo/v1/queue_pb2.py,sha256=j7pJim9qKMPODNCuDN0OVoQNK-F-BAeQT4CpPxupewo,21202
14
- ringo_task_queue/_proto/ringo/v1/queue_pb2_grpc.py,sha256=CyTaOnz6wmmYoExK-i3l37t2HhDO_0OEsUN0HwbN0lo,34673
15
- ringo_task_queue/bin/manifest.json,sha256=sDbQCxjIADwk7m9ZO9EXlsNTP5KWlt8QP_GtXHY6L-o,609
16
- ringo_task_queue/bin/ringo-task-queue-windows-amd64.exe,sha256=zNdAv1QgFy0UAH6PFzcHdWoR-hmrqg2rPj9-57K1Bo8,23388160
17
- ringo_task_queue-0.1.0.dev7.dist-info/METADATA,sha256=IsImWypd67VnyKf6iNS0-cXJa1u8-6d_Sh5HDrNFqeo,20207
18
- ringo_task_queue-0.1.0.dev7.dist-info/WHEEL,sha256=A7YmR1UrJozxyeLCzQFwQUdR7CRUwkFKasEDmnrjVxY,94
19
- ringo_task_queue-0.1.0.dev7.dist-info/licenses/LICENSE,sha256=yK3nnJz_bbOAPlcJqAooYcvecNJnBH9miT_X8Qrerv4,1086
20
- ringo_task_queue-0.1.0.dev7.dist-info/RECORD,,