pub struct InstrumentLocks { /* private fields */ }Expand description
Per-instrument command serialization: one trading command at a time on each instrument.
The lock is keyed by [InstrumentKey] (symbol and mic), not by the whole [InstrumentId]: the
same instrument reached through a ticker, a uid or a figi is still one instrument. Waiters are
served in the order they asked (the lock is FIFO), so a cancel sent before a place reaches the
broker before it. Why: the broker’s command channel is not ordered, and a place that overtakes
a cancel would act on a different book than the caller intended.
Different instruments do not wait for each other. The lock is released when the guard is dropped, on every exit path, including errors and cancelled futures.
bind and instrument_of remember which instrument a cid
belongs to, for commands that carry only a cid (cancel, replace).
§Examples
use brokapi_core::{ClientOrderId, InstrumentId, InstrumentKey, NativeId};
use brokapi_runtime::InstrumentLocks;
let sber = InstrumentId::new(
InstrumentKey::new("SBER", "TQBR"),
NativeId::TickerClass { ticker: "SBER".into(), class_code: "TQBR".into() },
);
let locks = InstrumentLocks::new();
let cid = ClientOrderId::new_v4();
locks.bind(cid, &sber);
// A place holds the instrument while its command is on the wire.
let guard = locks.lock(&sber).await;
assert!(locks.is_busy(&sber));
drop(guard);
assert!(!locks.is_busy(&sber));
// A cancel carries only the cid. It finds the instrument and takes the same lock.
let guard = locks.lock_cid(cid).await;
assert!(guard.is_some() && locks.is_busy(&sber));Implementations§
Source§impl InstrumentLocks
impl InstrumentLocks
Sourcepub async fn lock(&self, instrument: &InstrumentId) -> InstrumentGuard
pub async fn lock(&self, instrument: &InstrumentId) -> InstrumentGuard
Waits for earlier commands on instrument, then holds it until the guard drops.
Sourcepub fn is_busy(&self, instrument: &InstrumentId) -> bool
pub fn is_busy(&self, instrument: &InstrumentId) -> bool
Whether a command on the instrument is on the wire right now. For tests and diagnostics: the answer can be stale by the time the caller acts on it.
Sourcepub fn bind(&self, cid: ClientOrderId, instrument: &InstrumentId)
pub fn bind(&self, cid: ClientOrderId, instrument: &InstrumentId)
Remembers the instrument of an order we placed.
Sourcepub fn forget(&self, cid: ClientOrderId)
pub fn forget(&self, cid: ClientOrderId)
Forgets the instrument of a cid, for an order that is long finished. A later cancel of that cid is no longer serialized with the other commands of its instrument.
Sourcepub fn instrument_of(&self, cid: ClientOrderId) -> Option<InstrumentId>
pub fn instrument_of(&self, cid: ClientOrderId) -> Option<InstrumentId>
The instrument of a cid, if this process placed (or replaced) it.
Sourcepub async fn lock_cid(&self, cid: ClientOrderId) -> Option<InstrumentGuard>
pub async fn lock_cid(&self, cid: ClientOrderId) -> Option<InstrumentGuard>
Locks the instrument of cid when it is known. None: an order from before this process
started, its commands are not serialized with the others.