Refs #40
File: crates/charon-core/src/queue.rs
PR branch: feat/15-profit-calc-and-queue
Problem:
OpportunityQueue wraps std::collections::BinaryHeap. In the Charon architecture the scanner task pushes new opportunities and the executor task pops the best one — two separate tokio::spawn tasks. BinaryHeap is neither Sync nor Send when held across await points in multiple tasks without explicit synchronization.
The PR does not wrap OpportunityQueue in Arc<Mutex<...>> or Arc<tokio::sync::Mutex<...>>, nor expose a channel-based interface. The 5 unit tests are all single-threaded and will compile and pass while hiding this gap entirely.
Without synchronization the only safe usage is single-threaded sequential access, which contradicts the design intent and the scanner/executor split shown in the PRD architecture.
PRD clause: PRD architecture — scanner and executor run as independent async tasks; queue is the handoff point between them.
Impact: PR is architecturally incomplete. The type cannot be shared between scanner and executor tasks as currently designed.
Fix: Internalize synchronization. Wrap the BinaryHeap in a tokio::sync::Mutex inside OpportunityQueue and expose async fn push() and async fn pop() methods. Or document that callers must wrap in Arc<Mutex> and provide a usage example in an integration test. Add a concurrent push/pop test using tokio::spawn.
Refs #40
File: crates/charon-core/src/queue.rs
PR branch: feat/15-profit-calc-and-queue
Problem:
OpportunityQueue wraps std::collections::BinaryHeap. In the Charon architecture the scanner task pushes new opportunities and the executor task pops the best one — two separate tokio::spawn tasks. BinaryHeap is neither Sync nor Send when held across await points in multiple tasks without explicit synchronization.
The PR does not wrap OpportunityQueue in Arc<Mutex<...>> or Arc<tokio::sync::Mutex<...>>, nor expose a channel-based interface. The 5 unit tests are all single-threaded and will compile and pass while hiding this gap entirely.
Without synchronization the only safe usage is single-threaded sequential access, which contradicts the design intent and the scanner/executor split shown in the PRD architecture.
PRD clause: PRD architecture — scanner and executor run as independent async tasks; queue is the handoff point between them.
Impact: PR is architecturally incomplete. The type cannot be shared between scanner and executor tasks as currently designed.
Fix: Internalize synchronization. Wrap the BinaryHeap in a tokio::sync::Mutex inside OpportunityQueue and expose async fn push() and async fn pop() methods. Or document that callers must wrap in Arc<Mutex> and provide a usage example in an integration test. Add a concurrent push/pop test using tokio::spawn.