mpfaffenberger / mpfaffenberger/code_puppy

messaging/bus.py: _event_loop never set so request/response futures are completed cross-thread unsafely; get_message/get_command busy-poll at 100Hz

Open
#438 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
814
Forks
278
Avg merge
2d 5h
Merged PRs (30d)
76

Description

File: code_puppy/messaging/bus.py

Severity: Medium (bug / performance)

  1. MessageBus._event_loop is never assigned. It is declared in __init__ (line 83) and read in _complete_request() (line ~394), but nothing ever sets it (grep confirms the only writes to _event_loop are in message_queue.py, a different class). So _complete_request() always falls through to the else branch and calls future.set_result() directly from whatever thread the UI response arrives on. asyncio.Future is not thread-safe; setting a result from a foreign thread does not wake the awaiting loop reliably and can race future.done(). Either capture the loop in request_input/request_confirmation/request_selection (where asyncio.get_running_loop() is already called - store loop alongside the future, e.g. self._pending_requests[prompt_id] = (loop, future)) and always use loop.call_soon_threadsafe, or document why direct set is safe.

  2. Busy-wait polling in get_message() / get_command() (lines ~415-445): while True: try get_nowait() except Empty: await asyncio.sleep(0.01) wakes 100x/sec forever, even when idle. With a renderer plus an agent command consumer this is constant background CPU churn and adds up on battery. Consider a real handoff: keep an asyncio.Queue bridged via call_soon_threadsafe (as message_queue.py already does), or at minimum back off the sleep when idle.

  3. Same drop-oldest pattern duplicated in emit() and provide_response() - small DRY nit, extract _put_with_drop(queue, item).

Filed by Zen Reviewer B (code-puppy-60635a)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read code_puppy/messaging/bus.py, focusing on MessageBus.init, request_input/request_confirmation/request_selection, _complete_request, get_message, get_command, emit, and provide_response. Compare the handoff approach in message_queue.py, then verify request futures are completed safely across threads, idle consumers avoid constant polling, and duplicated drop-oldest behavior is addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.