feat(python): AsyncDaemon with async status() (partial #65)#78
Conversation
Next incremental step on #65 (native async API). Adds AsyncDaemon as a counterpart to the sync Daemon class, mirroring the AsyncSerialMonitor pattern from PR #73. - AsyncDaemon is purely additive — the sync Daemon class keeps all its methods and behavior. - Exposes async status() as the first method. Like reset_device on AsyncSerialMonitor, status is stateless HTTP so it ports without needing the cross-await state refactor. Future work on #65: async ensure_running(), async stop(), and then the WebSocket-backed AsyncSerialMonitor methods once the shared state is Send + Sync across await points. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughA new Python-exposed Rust class Changes
Sequence Diagram(s)sequenceDiagram
participant Python as Python Client
participant Async as AsyncDaemon
participant Tokio as Tokio Runtime
participant HTTP as HTTP Client
participant Daemon as Daemon API
Python->>Async: status(py)
activate Async
Async->>Tokio: spawn async task
activate Tokio
Tokio->>HTTP: GET /api/daemon/info
activate HTTP
HTTP->>Daemon: send request
activate Daemon
Daemon-->>HTTP: response
deactivate Daemon
HTTP-->>Tokio: response body
deactivate HTTP
Tokio->>Tokio: parse JSON
Tokio-->>Async: future result
deactivate Tokio
Async->>Async: convert to Python
Async-->>Python: PyResult<Bound<PyAny>>
deactivate Async
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Extends the AsyncDaemon scaffold (PR #78) with the method set that #65 explicitly targets: "Daemon/DaemonConnection: send_op and any other HTTP call". Added: - `send_op_async`: tokio/reqwest counterpart to `send_op` that yields on I/O instead of blocking a runtime thread. - `AsyncDaemon.ensure_running` / `AsyncDaemon.stop`: native async lifecycle calls so callers no longer need `_run_in_thread` for daemon bring-up/shutdown. - `AsyncDaemonConnection`: new class mirroring `DaemonConnection` with async `build`, `deploy`, `monitor`, and their `_result` counterparts. Shares `parse_outcome` / `outcome_to_pydict` with the sync class so the structured-result schema stays identical. - `connect_daemon_async` factory. Re-exports: `AsyncDaemon`, `AsyncDaemonConnection`, `connect_daemon_async` from `fbuild`; `AsyncSerialMonitor` from `fbuild.api`. Still remaining for #65: `AsyncSerialMonitor.read_lines` / `write` / `write_json_rpc`. These need the shared WebSocket state refactored to be `Send + Sync` across `.await` points (noted in the scaffold comment) and are a follow-up PR. Tests: 3 new Rust tests spin a minimal in-process HTTP mock and exercise `send_op_async` against success, failure, and connection- error paths. Failure outcomes must still carry `message` / `exit_code` / `stderr` so async callers retain the structured-result parity with the sync API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends the AsyncDaemon scaffold (PR #78) with the method set that #65 explicitly targets: "Daemon/DaemonConnection: send_op and any other HTTP call". Added: - `send_op_async`: tokio/reqwest counterpart to `send_op` that yields on I/O instead of blocking a runtime thread. - `AsyncDaemon.ensure_running` / `AsyncDaemon.stop`: native async lifecycle calls so callers no longer need `_run_in_thread` for daemon bring-up/shutdown. - `AsyncDaemonConnection`: new class mirroring `DaemonConnection` with async `build`, `deploy`, `monitor`, and their `_result` counterparts. Shares `parse_outcome` / `outcome_to_pydict` with the sync class so the structured-result schema stays identical. - `connect_daemon_async` factory. Re-exports: `AsyncDaemon`, `AsyncDaemonConnection`, `connect_daemon_async` from `fbuild`; `AsyncSerialMonitor` from `fbuild.api`. Still remaining for #65: `AsyncSerialMonitor.read_lines` / `write` / `write_json_rpc`. These need the shared WebSocket state refactored to be `Send + Sync` across `.await` points (noted in the scaffold comment) and are a follow-up PR. Tests: 3 new Rust tests spin a minimal in-process HTTP mock and exercise `send_op_async` against success, failure, and connection- error paths. Failure outcomes must still carry `message` / `exit_code` / `stderr` so async callers retain the structured-result parity with the sync API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Next incremental step on #65 (native async Python API). Adds `AsyncDaemon` as a counterpart to the sync `Daemon` class, mirroring the `AsyncSerialMonitor` pattern from PR #73.
Changes
Follow-up (tracked in #65)
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit