Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Windows: peers.py inbox read crashes on os.O_NONBLOCK (bare use; defensive getattr form already used elsewhere) — and the read receipt is persisted before the crash

未关闭
#5,511 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

  • #5512 来自 @Jah-yee —— 已关闭,未合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
38/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
python
领域
backend

调研方向

Start with loopx/control_plane/collaboration/peers.py at input_readiness() and compare its os.O_NONBLOCK use with the defensive forms in loopx/collaboration_mcp.py and loopx/control_plane/todos/completion_result.py. Reproduce on Windows with an inbox brief containing inputs; done means the read no longer crashes and the persisted receipt behavior is understood.

由索引模型根据 Issue 内容生成。

描述

Summary

On Windows, peers.py's inbox read path crashes unconditionally whenever a peer request brief carries inputs, because input_readiness() uses os.O_NONBLOCK — an attribute that does not exist on Windows. Two properties make this worse than a plain crash:

  1. It is on the main read path (read_inbox() → input_readiness(), peers.py), triggered by any brief with staged inputs — including the brief shapes in this repo's own test fixtures.
  2. The read receipt is persisted before the crash. After the AttributeError, an after-the-fact look at reads/<request_id>.json shows a recorded read (kind=receiver_cli_read, read_at set) even though the read actually failed — the receipt systematically misreports the outcome.

A one-line fix matches the pattern already used elsewhere in this same codebase (see below).

Repro (Windows, current main)

git rev-parse HEAD          # d74554b48...
python -c "import os; print(hasattr(os, 'O_NONBLOCK'))"   # False on win32

Then call the read path with a brief that has inputs (sandbox registry + workspace, minimal peers.request(...) followed by read_inbox(...)):

File "...\loopx\control_plane\collaboration\peers.py", line 547, in input_readiness
    os.open(path, os.O_RDONLY | os.O_NONBLOCK)
AttributeError: module 'os' has no attribute 'O_NONBLOCK'
  • Crash frame chain: read_inbox → input_readiness (line 547 on current main; 523 on v1.2.2).
  • Before raising, the receipt reads/<request_id>.json is already on disk with kind=receiver_cli_read and read_at written.
  • Briefs without an inputs key do not hit the path (the staging guard returns early) — the failure is deterministic for any input-bearing brief on Windows, and retrying cannot succeed.

The fix already exists in this repo — twice

The defensive form is used elsewhere; only peers.py is bare (both verified on current main, git grep -n "O_NONBLOCK" upstream/main):

  • loopx/collaboration_mcp.py:867 — getattr(os, "O_NONBLOCK", 0)
  • loopx/control_plane/todos/completion_result.py:32 — getattr(os, "O_NONBLOCK", 0)
  • vs. loopx/control_plane/collaboration/peers.py:547 — bare os.O_NONBLOCK

Suggested fix for peers.py (one line, consistent with those two precedents):

os.open(path, os.O_RDONLY | getattr(os, "O_NONBLOCK", 0))

On POSIX this is behavior-identical; on Windows the readiness probe degrades to a blocking open (or can be skipped, matching whatever the other call sites intend).

Impact notes

  • Platform: Windows (any brief with inputs); POSIX unaffected.
  • The persisted-but-failed receipt is the nastier half: any later audit of reads/ concludes the read succeeded. If there is a preferred outcome (e.g. record the read only after readiness succeeds, or record a failure kind), that would fix the misreport too — we're flagging it rather than prescribing, since the receipt-ordering may be intentional for crash recovery.

Our context

We hit this while operating a research squad on Windows against dsh 0.2.0rc2: three parallel workers all died on read_inbox with empty stdout/stderr, and the leftover receipts initially made it look like the reads had succeeded. Happy to turn the fix into a PR if the approach above is agreed — or an alternative if maintainers prefer dropping the readiness probe on Windows.

主要语言
Python
星标
6.2k
派生
596
平均合并
7 小时 35 分钟
30 天内合并 PR
928

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

loopx-project/loopx 的其他 Issue

查看 loopx-project/loopx 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。