refactor: wire AppContext into dispatcher and migrate cancel module (#639 phase 2) - #652
Conversation
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Caution Review failedPull request was closed or merged during review WalkthroughRefactors handlers to use dependency-injected Changes
Sequence Diagram(s)sequenceDiagram
rect rgba(200,220,255,0.5)
participant Run as RunLoop
participant Ctx as AppContext
participant Handler as handle_message_action
participant Cancel as cancel_action_with_ctx
participant DB as DatabasePool
participant LN as LndConnector
end
Run->>+Ctx: build AppContext(from_globals)
Run->>+Handler: handle_message_action(msg, ctx)
Handler->>+Cancel: cancel_action_with_ctx(ctx, msg, event, keys, ln_client)
Cancel->>+DB: ctx.pool() -> execute cancel flow
Cancel->>+LN: use ln_client for lightning ops
Cancel-->>-Handler: Result
Handler-->>-Run: Result propagation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
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 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/app.rs (1)
33-35: RouteCancelthroughcancel_action_with_ctx().The cancel module already exposes the DI entry point, but the dispatcher still unwraps
ctx.pool()itself and calls the legacy signature. Using the wrapper here keeps the context-to-pool translation insidesrc/app/cancel.rsand makes the migration pattern consistent.♻️ Suggested cleanup
-use crate::app::cancel::cancel_action; +use crate::app::cancel::cancel_action_with_ctx; @@ - Action::Cancel => cancel_action(msg, event, my_keys, ctx.pool(), ln_client) + Action::Cancel => cancel_action_with_ctx(ctx, msg, event, my_keys, ln_client) .await .map_err(|e| e.into()),Also applies to: 262-263
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app.rs` around lines 33 - 35, The dispatcher in app.rs currently calls the legacy cancel_action by unwrapping ctx.pool() and passing the pool directly; replace that call with cancel_action_with_ctx(ctx) so the context-to-pool translation stays inside the cancel module (use the DI entry point cancel_action_with_ctx instead of calling cancel_action(ctx.pool().unwrap(), ...)), and do the same substitution for the other occurrence referenced (lines ~262-263) to keep migration consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/context.rs`:
- Around line 19-33: The example docs currently call cancel_action(ctx, ...) but
the exported DI entry point is cancel_action_with_ctx and the original
cancel_action still expects &Pool<Sqlite>; update the example to call
cancel_action_with_ctx and adjust the parameters to match its signature (use
AppContext-derived ctx usage as in other examples), e.g., replace
cancel_action(...) with cancel_action_with_ctx(ctx, msg, event, my_keys,
ln_client) and ensure the example imports/uses AppContext and obtains ctx via
the same DI pattern used elsewhere in the file (refer to AppContext,
cancel_action_with_ctx, and pool()/settings() usages to align the example).
---
Nitpick comments:
In `@src/app.rs`:
- Around line 33-35: The dispatcher in app.rs currently calls the legacy
cancel_action by unwrapping ctx.pool() and passing the pool directly; replace
that call with cancel_action_with_ctx(ctx) so the context-to-pool translation
stays inside the cancel module (use the DI entry point cancel_action_with_ctx
instead of calling cancel_action(ctx.pool().unwrap(), ...)), and do the same
substitution for the other occurrence referenced (lines ~262-263) to keep
migration consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d4b7ee59-3f7d-444c-a1ec-bb4ae04e07f1
📒 Files selected for processing (3)
src/app.rssrc/app/cancel.rssrc/app/context.rs
grunch
left a comment
There was a problem hiding this comment.
Three issues to fix before merge:
- Double-wrapping the Nostr client
let nostr_client = Arc::new(get_nostr_client()?.clone());
Client in nostr-sdk is already an Arc-backed handle internally — cloning it gives a second handle sharing the same relay pool. Wrapping that clone in another Arc is redundant and will cause Arc::try_unwrap() to fail unexpectedly for anyone expecting exclusive ownership in future phases. Either store the cloned Client directly, or if you need Arc, clone the outer Arc from the global rather than creating a new one.
- ctx is a snapshot — document it
from_globals() is called once before the while loop, capturing Client and Settings at that moment. If the Nostr client reconnects or settings are reloaded at runtime, ctx will hold stale references. The pool is fine (it's an Arc to the same pool). Add an explicit comment:
// NOTE: ctx captures Client and Settings at startup. If either is
// reloaded at runtime, rebuild ctx or access them via globals directly.
let ctx = AppContext::from_globals()
.expect("Failed to build AppContext — globals not initialized");
Without this, whoever maintains this code will assume ctx is always fresh.
- handle_message_action has two sources of truth for the pool
async fn handle_message_action(
...
pool: &Pool<Sqlite>, // used by 18 handlers
ln_client: &mut LndConnector,
ctx: &AppContext, // ctx.pool() is the same pool
)
Both pool and ctx.pool() point to the same SqlitePool. This is expected during migration, but without a comment it looks like a mistake. Add:
// pool: legacy parameter kept during migration; new handlers use ctx.pool() instead.
// Remove once all handlers are migrated (issue #639).
|
Good review — I verified each point against current code and applied only what was needed in
Validation:
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Phase 2 of #639 — Wire AppContext into event loop + migrate cancel.rs
Depends on #651 (Phase 1 — AppContext struct). This PR includes Phase 1 commits.
Changes
src/app.rs(dispatcher)AppContext::from_globals()once per loop iteration inrun()&ctxtohandle_message_action()ctx.pool()instead of the rawpoolparametersrc/app/cancel.rscancel_action_with_ctx(&AppContext, ...)— new DI-based entry pointcancel_action(pool, ...)preserved as legacy wrapper (no breaking changes)cancel_cooperative_execution_step_*,cancel_order_by_*, etc.) still accept&Pool<Sqlite>directly — they get it from the callerMigration pattern demonstrated
This PR establishes the pattern for all remaining modules:
*_with_ctxvariant that takes&AppContextctxpoolfrom the_with_ctxcallerOnce all modules are migrated, the legacy wrappers and
poolparameter inhandle_message_actioncan be removed.What comes next
AppContexttest utilitiesValidation
cargo fmt✅cargo clippy --all-targets --all-features -- -D warnings✅cargo test✅ (186 passing)Part of #639
Summary by CodeRabbit