diff --git a/README.md b/README.md index 1090eb3d..2d510adb 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ aimdb --connect tcp://hub.local:7001 graph dot | dot -Tsvg > fleet.svg aimdb --connect serial:///dev/ttyACM0?baud=115200 record list ``` -Or point an AI client at the built-in [MCP server](tools/aimdb-mcp/) and ask: *"What is the current temperature at station alpha?"* +Or point an AI client at the built-in [MCP server](tools/aimdb-mcp/) (also [listed on Glama](https://glama.ai/mcp/servers/aimdb-dev/aimdb)) and ask: *"What is the current temperature at station alpha?"* ## Use it from your language diff --git a/aimdb-sync/README.md b/aimdb-sync/README.md index af4d7565..3b6b7f1f 100644 --- a/aimdb-sync/README.md +++ b/aimdb-sync/README.md @@ -7,7 +7,7 @@ Synchronous API wrapper for AimDB. `aimdb-sync` provides a synchronous interface to AimDB for code that does not use an async executor. Perfect for FFI bindings, legacy codebases, simple scripts, and situations where async is impractical. **Key Features:** -- **Pure Sync Context**: Works in plain `fn main()` - no `#[tokio::main]` required +- **Pure Sync Context**: Works in plain `fn main()` - no `#[tokio::main]` required. Blocking calls panic if made from async code inside a Tokio runtime - **Synchronous API**: Produce and consume records without `async` or `await` - **Thread-Safe**: `SyncProducer` type is `Send + Sync`, shareable across threads. `SyncConsumer` type is `Send` only, can be moved to another thread. - **Type-Safe**: Full compile-time type safety with generics @@ -55,11 +55,10 @@ aimdb-tokio-adapter = "0.7" use aimdb_core::{AimDbBuilder, buffer::BufferCfg}; use aimdb_sync::AimDbBuilderSyncExt; use aimdb_tokio_adapter::{TokioAdapter, TokioRecordRegistrarExt}; -use serde::{Deserialize, Serialize}; use std::sync::Arc; use std::time::Duration; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone)] struct Temperature { celsius: f32, sensor_id: String, @@ -300,7 +299,8 @@ builder.configure::("my-data", |reg| { reg.buffer(BufferCfg::SingleLatest); }); -// Mailbox: One pending value. Reading removes it +// Mailbox: One pending value. A new value overwrites an unread one, and with +// several consumers each value is taken by only one of them builder.configure::("my-data", |reg| { reg.buffer(BufferCfg::Mailbox); }); @@ -336,7 +336,7 @@ fn main() -> Result<(), Box> { ```rust use aimdb_core::{AimDbBuilder, buffer::BufferCfg}; -use aimdb_sync::{AimDbBuilderSyncExt, AimDbHandle}; +use aimdb_sync::{AimDbBuilderSyncExt, AimDbHandle, SyncConsumer, SyncProducer}; use aimdb_tokio_adapter::{TokioAdapter, TokioRecordRegistrarExt}; use std::sync::Arc; use std::time::Duration; @@ -344,6 +344,10 @@ use std::time::Duration; // Wrap async AimDB for legacy sync code pub struct LegacyAdapter { handle: AimDbHandle, + producer: SyncProducer, + // Kept for the adapter's lifetime: a new SPMC consumer only sees values + // produced after it subscribes. + consumer: SyncConsumer, } impl LegacyAdapter { @@ -356,22 +360,18 @@ impl LegacyAdapter { }); let handle = builder.attach()?; - Ok(Self { handle }) + let producer = handle.producer::("sensor-data")?; + let consumer = handle.consumer::("sensor-data")?; + Ok(Self { handle, producer, consumer }) } pub fn send_sensor_data(&self, data: SensorData) -> Result<(), String> { - let producer = self.handle.producer::("sensor-data") - .map_err(|e| e.to_string())?; - - producer.set(data) + self.producer.set(data) .map_err(|e| e.to_string()) } - pub fn read_sensor_data(&self) -> Result { - let mut consumer = self.handle.consumer::("sensor-data") - .map_err(|e| e.to_string())?; - - consumer.get_with_timeout(Duration::from_secs(1)) + pub fn read_sensor_data(&mut self) -> Result { + self.consumer.get_with_timeout(Duration::from_secs(1)) .map_err(|e| e.to_string()) } diff --git a/tools/aimdb-mcp/README.md b/tools/aimdb-mcp/README.md index 240405e2..e6bcd09e 100644 --- a/tools/aimdb-mcp/README.md +++ b/tools/aimdb-mcp/README.md @@ -1,5 +1,7 @@ # aimdb-mcp +[![aimdb-mcp MCP server](https://glama.ai/mcp/servers/aimdb-dev/aimdb/badges/score.svg)](https://glama.ai/mcp/servers/aimdb-dev/aimdb) + Model Context Protocol (MCP) server for AimDB - enables LLM-powered introspection and debugging. ## Overview