xbbg-async 1.4.12

Async worker-pool engine over xbbg_core for Bloomberg API requests and subscriptions
docs.rs failed to build xbbg-async-1.4.12
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

xbbg-async

Async worker-pool engine over xbbg-core for Bloomberg API requests and subscriptions.

Architecture

Engine
├── RequestWorkerPool        (round-robin dispatch, default 2 workers)
│   └── Worker threads       each owns a Session + Slab<UnifiedRequestState>
│       └── 12 state machines: RefData, HistData, BulkData, IntradayBar,
│           IntradayTick, HistDataStream, IntradayBarStream,
│           IntradayTickStream, Generic, Bql, Bsrch, FieldInfo
├── SubscriptionSessionPool  (1 pre-warmed session, 32-session cap by default)
│   └── Sub-worker threads   each owns a Session + Slab<SubscriptionState>
├── SchemaCache              (in-memory + disk-persisted service schemas)
├── FieldCache               (global, disk-persisted field type resolution)
└── Tokio Runtime

Each worker thread owns its own Bloomberg Session — no Arc<Session>, no shared state, no contention. Requests are dispatched round-robin across the pool; subscriptions are claimed from a separate session pool.

Key modules

Module Purpose
engine/ Engine startup, shutdown, command dispatch
engine/worker/ Per-worker event loop and request lifecycle
engine/subscription_pool.rs Per-session subscription lifecycle and callbacks
engine/state/ 12 state machines for different Bloomberg operations
schema/ Service schema introspection + disk cache
field_cache.rs Global field-type resolver with disk persistence
errors.rs BlpAsyncError — async-layer error type

Design decisions

  • One Session per thread — Bloomberg's Session is not Sync. Rather than wrapping it in a Mutex, each worker owns its session outright, eliminating contention entirely.
  • Slab-based correlation — In-flight requests are tracked with a Slab, giving O(1) insert/remove and compact memory layout.
  • Schema + field caching — Service schemas and field metadata are cached to disk, avoiding repeated introspection on startup.

Subscription deltas and termination

SubscriptionStream::next() yields sparse SubscriptionUpdate values. Missing UpdateField entries mean unchanged; UpdateValue::Null is an explicit SDK clear. Requested arrays/complex values and non-null decode failures are errors. All-fields mode omits unrequested nonscalars without suppressing a later scalar.

Arrow conversion appends non-null binary __xbbg_present. Bit i, LSB-first, maps to schema field i + 2 after timestamp and topic. A present-null field sets its bit; absence does not. Interpret against each batch's current schema; xbbg.subscription_presence metadata records the encoding and mapping.

The bounded subscription channel reserves terminal errors outside data capacity. It yields committed data, one terminal error, then EOF even when sender handles remain. Bloomberg DATALOSS, DropNewest overflow, and Block forwarding overflow/timeout terminate with BlpError::SubscriptionDataLoss; resubscribe for a fresh image. Unattributed/session-wide loss uses topic="*". The SDK callback never waits for consumer space.

Draining unsubscribe propagates unread failures after cleanup rather than returning a successful partial result. Removing every topic does not detach the handle from engine/session termination. Partial-topic failures and ordinary connection-down notifications retain their nonterminal behavior.