simulator_client/
transaction_step.rs1use std::time::Duration;
2
3use simulator_api::{
4 BacktestRequest, BacktestResponse, ContinueToParams, DiscoveryBatchEvent, PausedEvent,
5};
6
7use crate::{BacktestClientError, BacktestClientResult, BacktestSession};
8
9#[derive(Debug, Clone)]
11pub struct DiscoveryPause {
12 pub discovery: DiscoveryBatchEvent,
14 pub paused: PausedEvent,
16}
17
18#[derive(Debug)]
20pub enum DiscoveryStepResult {
21 Paused(DiscoveryPause),
24 Completed,
26}
27
28impl BacktestSession {
29 pub async fn advance_to_discovery(
41 &mut self,
42 timeout: Option<Duration>,
43 ) -> BacktestClientResult<DiscoveryStepResult> {
44 let Some(response) = self.next_response(timeout).await? else {
46 return Err(BacktestClientError::Closed {
47 reason: "websocket closed while waiting for DiscoveryBatch".to_string(),
48 });
49 };
50 let discovery: DiscoveryBatchEvent = match response {
51 BacktestResponse::DiscoveryBatch(event) => event,
52 BacktestResponse::Error(err) => return Err(BacktestClientError::Remote(err)),
53 other => {
54 return Err(BacktestClientError::UnexpectedResponse {
55 context: "waiting for DiscoveryBatch",
56 response: Box::new(other),
57 });
58 }
59 };
60
61 self.send(
63 &BacktestRequest::ContinueTo(ContinueToParams {
64 slot: discovery.slot,
65 batch_index: Some(discovery.batch_index),
66 }),
67 timeout,
68 )
69 .await?;
70
71 let mut pending_discoveries: Vec<BacktestResponse> = Vec::new();
76 let paused: PausedEvent = loop {
77 let Some(response) = self.next_response(timeout).await? else {
78 return Err(BacktestClientError::Closed {
79 reason: "websocket closed while waiting for Paused after ContinueTo"
80 .to_string(),
81 });
82 };
83 tracing::debug!("<- advance {response:?}");
84 match response {
85 BacktestResponse::Paused(event) => {
86 self.ready_for_continue = true;
87 for d in pending_discoveries {
88 self.push_backlog(d);
89 }
90 break event;
91 }
92 next @ BacktestResponse::DiscoveryBatch(_) => {
93 pending_discoveries.push(next);
94 }
95 BacktestResponse::SlotNotification(_)
96 | BacktestResponse::Status { .. }
97 | BacktestResponse::Success
98 | BacktestResponse::ReadyForContinue => {}
99 BacktestResponse::Completed { .. } => {
100 return Ok(DiscoveryStepResult::Completed);
101 }
102 BacktestResponse::Error(err) => return Err(BacktestClientError::Remote(err)),
103 other => {
104 return Err(BacktestClientError::UnexpectedResponse {
105 context: "waiting for Paused after ContinueTo",
106 response: Box::new(other),
107 });
108 }
109 }
110 };
111
112 Ok(DiscoveryStepResult::Paused(DiscoveryPause {
113 discovery,
114 paused,
115 }))
116 }
117}