Skip to main content

aimdb_executor/
lib.rs

1//! AimDB Executor Traits
2//!
3//! Pure trait definitions for async execution across different runtime environments.
4//! Enables dependency inversion where the core database depends on abstractions
5//! rather than concrete runtime implementations.
6//!
7//! # Design Philosophy
8//!
9//! - **Runtime Agnostic**: No concrete runtime dependencies
10//! - **Simple Trait Structure**: 4 focused traits covering all runtime needs
11//! - **Platform Flexible**: Works across std and no_std environments
12//! - **Zero Dependencies**: Pure trait definitions with minimal coupling
13//!
14//! # Trait Structure
15//!
16//! 1. **`RuntimeAdapter`** - Platform identity and metadata
17//! 2. **`TimeOps`** - Time operations (now, sleep, duration helpers)
18//! 3. **`Logger`** - Structured logging (info, debug, warn, error)
19//! 4. **`Spawn`** - Task spawning with platform-specific tokens
20
21#![cfg_attr(not(feature = "std"), no_std)]
22
23use core::future::Future;
24
25pub mod join;
26pub use join::{JoinFanInRuntime, JoinQueue, JoinReceiver, JoinSender};
27
28// ============================================================================
29// Error Types
30// ============================================================================
31
32pub type ExecutorResult<T> = Result<T, ExecutorError>;
33
34#[derive(Debug)]
35#[cfg_attr(feature = "std", derive(thiserror::Error))]
36pub enum ExecutorError {
37    #[cfg_attr(feature = "std", error("Spawn failed: {message}"))]
38    SpawnFailed {
39        #[cfg(feature = "std")]
40        message: String,
41        #[cfg(not(feature = "std"))]
42        message: &'static str,
43    },
44
45    #[cfg_attr(feature = "std", error("Runtime unavailable: {message}"))]
46    RuntimeUnavailable {
47        #[cfg(feature = "std")]
48        message: String,
49        #[cfg(not(feature = "std"))]
50        message: &'static str,
51    },
52
53    #[cfg_attr(feature = "std", error("Task join failed: {message}"))]
54    TaskJoinFailed {
55        #[cfg(feature = "std")]
56        message: String,
57        #[cfg(not(feature = "std"))]
58        message: &'static str,
59    },
60
61    #[cfg_attr(feature = "std", error("Join queue closed"))]
62    QueueClosed,
63}
64
65// ============================================================================
66// Core Traits (Simplified - 4 traits total)
67// ============================================================================
68
69/// Core runtime adapter trait - provides identity
70pub trait RuntimeAdapter: Send + Sync + 'static {
71    fn runtime_name() -> &'static str
72    where
73        Self: Sized;
74}
75
76/// Time operations trait - enables ctx.time() accessor
77pub trait TimeOps: RuntimeAdapter {
78    type Instant: Clone + Send + Sync + core::fmt::Debug + 'static;
79    type Duration: Clone + Send + Sync + core::fmt::Debug + 'static;
80
81    fn now(&self) -> Self::Instant;
82    fn duration_since(
83        &self,
84        later: Self::Instant,
85        earlier: Self::Instant,
86    ) -> Option<Self::Duration>;
87    fn millis(&self, ms: u64) -> Self::Duration;
88    fn secs(&self, secs: u64) -> Self::Duration;
89    fn micros(&self, micros: u64) -> Self::Duration;
90    fn sleep(&self, duration: Self::Duration) -> impl Future<Output = ()> + Send;
91
92    /// Returns the number of whole nanoseconds in `duration`.
93    ///
94    /// Used by features (e.g. stage profiling) that need a numeric, runtime-agnostic
95    /// representation of an elapsed [`Self::Duration`]. Implementations should saturate
96    /// rather than overflow for durations larger than `u64::MAX` nanoseconds.
97    fn duration_as_nanos(&self, duration: Self::Duration) -> u64;
98}
99
100/// Logging trait - enables ctx.log() accessor
101pub trait Logger: RuntimeAdapter {
102    fn info(&self, message: &str);
103    fn debug(&self, message: &str);
104    fn warn(&self, message: &str);
105    fn error(&self, message: &str);
106}
107
108/// Task spawning trait - adapter-specific implementation
109pub trait Spawn: RuntimeAdapter {
110    type SpawnToken: Send + 'static;
111    fn spawn<F>(&self, future: F) -> ExecutorResult<Self::SpawnToken>
112    where
113        F: Future<Output = ()> + Send + 'static;
114}
115
116// ============================================================================
117// Convenience Trait Bundle
118// ============================================================================
119
120/// Complete runtime trait bundle
121pub trait Runtime: RuntimeAdapter + TimeOps + Logger + Spawn {
122    fn runtime_info(&self) -> RuntimeInfo
123    where
124        Self: Sized,
125    {
126        RuntimeInfo {
127            name: Self::runtime_name(),
128        }
129    }
130}
131
132// Auto-implement Runtime for any type with all traits
133impl<T> Runtime for T where T: RuntimeAdapter + TimeOps + Logger + Spawn {}
134
135#[derive(Debug, Clone)]
136pub struct RuntimeInfo {
137    pub name: &'static str,
138}