polyester/services/
mod.rs1mod api_keys;
4mod auth;
5mod balances;
6mod correlation_id;
7mod deposit_withdraw;
8mod market_data;
9mod orders;
10mod profile;
11mod scope;
12mod thin;
13mod triggers;
14mod unary;
15
16pub use api_keys::ApiKeysService;
17pub use auth::AuthService;
18pub use balances::BalancesService;
19pub use deposit_withdraw::{
20 DepositService, PreparedTradingWithdraw, WithdrawService, ZipperService,
21 new_trading_withdraw_idempotency_key, new_trading_withdraw_nonce,
22};
23pub use market_data::{
24 CreateSubscriptionOptions, ListMarketOverviewOptions, MarketDataService,
25 MarketOverviewCreateSubscriptionOptions, MarketOverviewService, OrderbookService,
26};
27pub use orders::{OrdersService, TradesService};
28pub use profile::ProfileService;
29pub use thin::*;
30pub use triggers::TriggersService;
31
32use crate::catalogs::Manager as CatalogManager;
33use crate::errors::{Error, Result};
34use crate::transport::Factory;
35use std::sync::Arc;
36use std::time::Duration;
37use tokio::sync::OnceCell;
38
39use crate::realtime::Client as RealtimeClient;
40
41#[derive(Clone)]
43pub struct ServiceContext {
44 pub factory: Factory,
45 pub catalogs: Arc<CatalogManager>,
46 pub default_sub_account_id: Option<String>,
47 pub default_account_id: Option<String>,
48 pub realtime: RealtimeClient,
49 pub catalog_ready: Arc<OnceCell<Result<()>>>,
50 pub hydrate_catalogs_enabled: bool,
51}
52
53impl ServiceContext {
54 pub async fn wait_for_catalogs(&self) -> Result<()> {
58 if !self.hydrate_catalogs_enabled {
59 return Ok(());
60 }
61 if self.catalogs.is_ready() {
62 return Ok(());
63 }
64 if let Some(result) = self.catalog_ready.get() {
65 return result.clone();
66 }
67 let deadline = tokio::time::Instant::now() + Duration::from_secs(30);
68 while self.catalog_ready.get().is_none() {
69 if self.catalogs.is_ready() {
70 return Ok(());
71 }
72 if tokio::time::Instant::now() >= deadline {
73 return Err(Error::validation(
74 "catalogs are not ready; await client.wait_for_catalogs() before placing orders",
75 ));
76 }
77 tokio::time::sleep(Duration::from_millis(5)).await;
78 }
79 if self.catalogs.is_ready() {
80 return Ok(());
81 }
82 self.catalog_ready.get().cloned().unwrap_or_else(|| {
83 Err(Error::validation(
84 "catalogs are not ready; await client.wait_for_catalogs() before placing orders",
85 ))
86 })
87 }
88}