pub trait MarketSource:
Send
+ Sync
+ 'static {
// Required methods
fn name(&self) -> &str;
fn run<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn is_live(&self) -> bool;
}Expand description
A source of live market data (WebSocket feed, backtest replay, simulator).
Implementors push events into the bot via the
MarketDataBus that the supervisor creates.
MarketSource is intended to be wrapped by a TradingService in
rustrade-supervisor so it inherits lifecycle management and
auto-restart; this trait just documents the contract on the data side.
§Example
A loopback source that publishes a single tick and exits. Production
sources hold the MarketDataBus sender they were constructed with
and publish to it from run.
use async_trait::async_trait;
use rustrade_core::{MarketSource, Result};
struct OneShotSource {
name: String,
}
#[async_trait]
impl MarketSource for OneShotSource {
fn name(&self) -> &str { &self.name }
async fn run(&self) -> Result<()> {
// In a real impl: connect to feed, loop publishing events to
// the bus, return Ok(()) on clean shutdown.
Ok(())
}
fn is_live(&self) -> bool { false }
}§Cancellation contract
run does not take a CancellationToken directly. Cancellation is
expected to flow through the wrapping TradingService — when the
supervisor cancels that service’s token, it drops the
MarketSource::run future at its next .await.
Implementors must therefore be drop-safe: any open resources (WebSocket connections, HTTP sessions, file handles) must release cleanly when their containing future is dropped. In practice this means:
- Use
tokio::select!against external events only inside your own loop, not against an externally-owned cancel signal here. - Don’t hold a
MutexGuardacross an.awaitthat could be dropped mid-flight — dropping a guard is fine, but holding one while the future is destructured can deadlock the lock. - If you need explicit teardown, perform it in a
Dropimpl on the implementing type rather than at the end ofrun.
Required Methods§
Sourcefn run<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn run<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Begin streaming events. Should run until the feed terminates or the caller drops the returned future (see the cancellation contract in the trait docs).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".