Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ build:
cargo build --package aimdb-tokio-adapter --features "tokio-runtime,tracing,observability"
@printf "$(YELLOW) → Building sync wrapper$(NC)\n"
cargo build --package aimdb-sync
@printf "$(YELLOW) → Building sync wrapper (no_std)$(NC)\n"
cargo build --package aimdb-sync --no-default-features
Comment thread
solus161 marked this conversation as resolved.
@printf "$(YELLOW) → Asserting no tokio in sync wrapper (no_std)$(NC)\n"
@out=$$(cargo tree -p aimdb-sync --no-default-features -e features,no-dev 2>&1) || { \
printf "$(RED)✗ cargo tree failed — refusing to pass vacuously:$(NC)\n"; \
printf '%s\n' "$$out"; exit 1; \
}; \
if printf '%s\n' "$$out" | grep -qi tokio; then \
printf "$(RED)✗ tokio leaked into the no_std build$(NC)\n"; \
printf '%s\n' "$$out" | grep -i tokio; exit 1; \
fi
@printf "$(BLUE)✓ no_std graph is tokio-free$(NC)\n"
@printf "$(YELLOW) → Building codegen library$(NC)\n"
cargo build --package aimdb-codegen
@printf "$(YELLOW) → Building CLI tools$(NC)\n"
Expand Down Expand Up @@ -157,6 +169,10 @@ test:
cargo test --package aimdb-wasm-adapter --no-default-features --features observability --lib
@printf "$(YELLOW) → Testing sync wrapper$(NC)\n"
cargo test --package aimdb-sync
@printf "$(YELLOW) → Testing sync wrapper (no_std)$(NC)\n"
cargo test --package aimdb-sync --no-default-features
@printf "$(YELLOW) → Testing sync wrapper (data-contracts: set_value family)$(NC)\n"
cargo test --package aimdb-sync --features data-contracts
@printf "$(YELLOW) → Testing codegen library$(NC)\n"
cargo test --package aimdb-codegen
@printf "$(YELLOW) → Testing CLI tools$(NC)\n"
Expand Down Expand Up @@ -240,6 +256,10 @@ clippy:
cargo clippy --package aimdb-embassy-adapter --target thumbv7em-none-eabihf --features "embassy-runtime,embassy-net-support" -- -D warnings
@printf "$(YELLOW) → Clippy on sync wrapper$(NC)\n"
cargo clippy --package aimdb-sync --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on sync wrapper (no_std)$(NC)\n"
cargo clippy --package aimdb-sync --no-default-features --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on sync wrapper (data-contracts)$(NC)\n"
cargo clippy --package aimdb-sync --features data-contracts --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on client library$(NC)\n"
cargo clippy --package aimdb-client --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on client library (serial transport arm)$(NC)\n"
Expand Down Expand Up @@ -392,6 +412,8 @@ test-embedded:
cargo check --package aimdb-tcp-connector --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "embassy-runtime"
@printf "$(YELLOW) → Checking aimdb-tcp-connector (Embassy TCP client + defmt) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-tcp-connector --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "embassy-runtime,defmt"
@printf "$(YELLOW) → Checking aimdb-sync (no_std) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-sync --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features

## Example projects
examples:
Expand Down
14 changes: 10 additions & 4 deletions aimdb-sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ categories = ["database", "api-bindings"]

[dependencies]
# Core dependencies
aimdb-core = { path = "../aimdb-core", version = "1.1.0" }
aimdb-tokio-adapter = { path = "../aimdb-tokio-adapter", version = "0.6.0" }
# `default-features = false` is load-bearing: aimdb-core's default set is
# ["std", "alloc", "derive"], so inheriting it would pull anyhow/serde/remote
# into the `--no-default-features` build and silently un-no_std this crate.
# The `std` feature below forwards to `aimdb-core/std` for the std path.
aimdb-core = { path = "../aimdb-core", version = "1.1.0", default-features = false, features = [
"alloc",
] }
aimdb-tokio-adapter = { path = "../aimdb-tokio-adapter", version = "0.6.0", optional = true }
tracing = { workspace = true, optional = true }

# Tokio for channels and runtime
tokio = { version = "1.40", features = ["sync", "rt", "time", "macros"] }
tokio = { version = "1.40", features = ["sync", "rt", "time", "macros"], optional = true }

# Error handling
thiserror = { version = "2.0.16", default-features = false }
Expand All @@ -38,7 +44,7 @@ serde_json = "1.0"
[features]
default = ["std"]

std = []
std = ["aimdb-core/std", "dep:tokio", "dep:aimdb-tokio-adapter"]

# Enable tracing for debugging
tracing = ["dep:tracing", "aimdb-core/tracing"]
Expand Down
14 changes: 5 additions & 9 deletions aimdb-sync/src/consumer.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Synchronous consumer for typed records.

use crate::{SyncError, SyncResult};
use std::fmt::Debug;
use alloc::sync::Arc;
use core::fmt::Debug;
use core::time::Duration;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::sync::Mutex;

/// Synchronous consumer for records of type `T`.
///
Expand Down Expand Up @@ -49,7 +50,7 @@ where
T: Send + Sync + 'static + Debug + Clone,
{
/// Channel receiver for consumer data
/// Wrapped in Arc<Mutex> so it can be shared but only one thread receives at a time
/// Wrapped in `Arc<Mutex>` so it can be shared but only one thread receives at a time
rx: Arc<Mutex<mpsc::Receiver<T>>>,
}

Expand Down Expand Up @@ -87,7 +88,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -127,7 +127,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -168,7 +167,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -216,7 +214,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -269,7 +266,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down
7 changes: 3 additions & 4 deletions aimdb-sync/src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

use crate::{SyncError, SyncResult};
use aimdb_core::{log_error, log_warn, AimDb, AimDbBuilder, DbError, DbResult};
use std::fmt::Debug;
use std::sync::Arc;
use alloc::sync::Arc;
use core::fmt::Debug;
use core::time::Duration;
use std::thread::{self, JoinHandle};
use std::time::Duration;
use tokio::sync::mpsc;

/// Default channel capacity for sync producers and consumers.
Expand Down Expand Up @@ -50,7 +50,6 @@ pub trait AimDbBuilderSyncExt {
/// use std::sync::Arc;
///
/// # #[derive(Debug, Clone)] struct MyData { value: f32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let mut builder = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter::new()?));
Expand Down
30 changes: 21 additions & 9 deletions aimdb-sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
//!
//! ## Quick Start
//!
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! use aimdb_core::{AimDbBuilder, buffer::BufferCfg};
//! use aimdb_tokio_adapter::{TokioAdapter, TokioRecordRegistrarExt};
//! use aimdb_sync::{AimDbBuilderSyncExt, SyncResult};
Expand All @@ -53,8 +54,6 @@
//! struct Temperature {
//! celsius: f32,
//! }
//! // Guard againts the use of TokioAdapter in case of "std"
//! # #[cfg(feature = "std")]
//! # fn main() -> SyncResult<()> {
//! // Build and attach database (NO #[tokio::main] NEEDED!)
//! let adapter = Arc::new(TokioAdapter::new()?);
Expand Down Expand Up @@ -87,7 +86,8 @@
//!
//! Both `SyncProducer` and `SyncConsumer` can be cloned and shared across threads:
//!
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! use std::thread;
//! # use aimdb_sync::{SyncConsumer, SyncProducer};
//! # #[derive(Debug, Clone)] struct Temperature { celsius: f32 }
Expand All @@ -114,7 +114,8 @@
//! Note: Cloning a `SyncConsumer` shares the same channel, so only one thread
//! will receive each value. For independent subscriptions, create multiple consumers:
//!
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # use aimdb_sync::{AimDbHandle, SyncResult};
//! # #[derive(Debug, Clone)] struct Temperature { celsius: f32 }
//! # fn demo(handle: &AimDbHandle) -> SyncResult<()> {
Expand All @@ -131,7 +132,8 @@
//! By default, both producers and consumers use a channel capacity of 100.
//! You can customize this per record type using the `_with_capacity` methods:
//!
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # use aimdb_sync::{AimDbHandle, SyncResult};
//! # #[derive(Debug, Clone)] struct SensorData { value: f32 }
//! # #[derive(Debug, Clone)] struct RareEvent { code: u8 }
Expand Down Expand Up @@ -167,7 +169,8 @@
//! ### Solutions for SingleLatest Semantics
//!
//! 1. **Use `get_latest()`** - Drains the channel to get the most recent value:
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # use aimdb_sync::SyncResult;
//! # #[derive(Debug, Clone)] struct Temperature { celsius: f32 }
//! # fn demo(consumer: &aimdb_sync::SyncConsumer<Temperature>) -> SyncResult<()> {
Expand All @@ -178,7 +181,8 @@
//! ```
//!
//! 2. **Use capacity=1** - Minimize queueing:
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # #[derive(Debug, Clone)] struct Temperature { celsius: f32 }
//! # fn demo(handle: &aimdb_sync::AimDbHandle) -> aimdb_sync::SyncResult<()> {
//! let consumer = handle.consumer_with_capacity::<Temperature>("sensor.temp", 1)?;
Expand Down Expand Up @@ -223,7 +227,8 @@
//! and return any errors that occur in the async context
//! - `try_set()` sends immediately without waiting for the produce result (fire-and-forget)
//!
//! ```no_run
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # use aimdb_sync::{DbError, SyncError, SyncProducer};
//! # use aimdb_core::{log_error};
//! # #[derive(Debug, Clone)] struct Temperature { celsius: f32 }
Expand All @@ -245,16 +250,23 @@
#![warn(missing_docs)]
#![warn(clippy::all)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

#[cfg(feature = "std")]
mod consumer;
mod error;
#[cfg(feature = "std")]
mod handle;
#[cfg(feature = "std")]
mod producer;

#[cfg(feature = "std")]
pub use consumer::SyncConsumer;
#[cfg(feature = "std")]
pub use handle::{AimDbBuilderSyncExt, AimDbHandle, AimDbSyncExt, DEFAULT_SYNC_CHANNEL_CAPACITY};
#[cfg(feature = "std")]
pub use producer::SyncProducer;

pub use error::{SyncError, SyncResult};
Expand Down
13 changes: 3 additions & 10 deletions aimdb-sync/src/producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use crate::{SyncError, SyncResult};
use aimdb_core::DbResult;
use std::fmt::Debug;
use std::sync::Arc;
use std::time::Duration;
use alloc::sync::Arc;
use core::fmt::Debug;
use core::time::Duration;
use tokio::sync::{mpsc, oneshot};

/// Synchronous producer for records of type `T`.
Expand Down Expand Up @@ -124,7 +124,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -161,7 +160,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -199,7 +197,6 @@ where
///
/// # #[derive(Debug, Clone)]
/// # struct MyData { value: i32 }
/// # #[cfg(feature = "std")]
/// # fn main() -> SyncResult<()> {
/// let handle = AimDbBuilder::new()
/// .runtime(Arc::new(TokioAdapter))
Expand Down Expand Up @@ -243,8 +240,6 @@ where
/// # Example
///
/// ```no_run
/// # #[cfg(feature = "data-contracts")]
/// # #[cfg(feature = "std")]
/// # use aimdb_sync::SyncResult;
/// # fn main() -> SyncResult<()> {
/// use aimdb_core::AimDbBuilder;
Expand Down Expand Up @@ -272,8 +267,6 @@ where
/// producer.set_value(22.5)?; // constructs Temperature::set(22.5, now_ms) and sends
/// # Ok(())
/// # }
/// # #[cfg(not(feature = "data-contracts"))]
/// # fn main() {}
/// ```
pub fn set_value(&self, value: T::Value) -> SyncResult<()> {
self.set(T::set(value, unix_now_ms()))
Expand Down
4 changes: 3 additions & 1 deletion aimdb-sync/tests/integration_test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Integration tests for aimdb-sync
//!
//! These tests verify end-to-end functionality of the synchronous API wrapper.

// The whole file exercises `attach()` / `SyncProducer` / `SyncConsumer`, none of
// which exist without `std`.
#![cfg(feature = "std")]
use aimdb_core::{buffer::BufferCfg, AimDbBuilder, DbError};
use aimdb_sync::AimDbBuilderSyncExt;
use aimdb_sync::SyncError;
Expand Down
2 changes: 1 addition & 1 deletion aimdb-sync/tests/settable_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! construct via `Settable::set`, produce, and consume end-to-end through the
//! real sync bridge.

#![cfg(feature = "data-contracts")]
#![cfg(all(feature = "std", feature = "data-contracts"))]

use aimdb_core::{buffer::BufferCfg, AimDbBuilder};
use aimdb_data_contracts::{SchemaType, Settable};
Expand Down
Loading