ai-store-sync
Blocking (synchronous) facade over [ai_store_core::Store].
Why
Store is async by design; the SPI traits (EventBackend, CacheBackend,
ProjectionSink) are async_trait. Consumers embedded in an otherwise
synchronous codebase would otherwise have to spin up a tokio::Runtime and
wrap every call in runtime.block_on(...), and get the details right
(current-thread vs multi-thread, runtime lifetime, Send bounds).
[BlockingStore] does that once, in-tree.
Choosing a constructor
- [
BlockingStore::new] — owns a dedicatedcurrent_threadruntime. Use this from a plain synchronousmain/ thread when the caller has no tokio runtime of its own. Analogous toreqwest::blocking::Client::new. - [
BlockingStore::with_handle] — borrows an existing [tokio::runtime::Handle]. Use this when the surrounding process already runs a runtime (e.g. a library that hosts tokio internally and hands aHandledown to sync plugin code).
Nested-runtime pitfall
Do not call a BlockingStore method from inside an async task on the
same tokio runtime — that would attempt to block_on from within a runtime
worker and will panic. If you must bridge from async code:
- prefer calling
Storedirectly with.await, or - wrap the blocking call in
tokio::task::block_in_placeon a multi-thread runtime.
Errors
All methods return [StoreError] verbatim from the async facade. No new
error variants are introduced.