Skip to main content

MarketSource

Trait MarketSource 

Source
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 MutexGuard across an .await that 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 Drop impl on the implementing type rather than at the end of run.

Required Methods§

Source

fn name(&self) -> &str

Short identifier for logging — typically the exchange name.

Source

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).

Source

fn is_live(&self) -> bool

Is the feed currently receiving data?

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§