@@ -25,19 +25,22 @@ const DEFAULT_CALL_TIMEOUT: Duration = Duration::from_secs(5);
2525/// |---------|-----------------|----------|-------------|
2626/// | `Async` | Tokio task | Non-blocking I/O, async operations | Blocks runtime if sync code runs too long |
2727/// | `Blocking` | Tokio blocking pool | Short blocking operations (file I/O, DNS) | Shared pool with limited threads |
28- /// | `Thread` | Dedicated OS thread | Long-running blocking work, CPU-heavy tasks | Higher memory overhead per GenServer |
28+ /// | `Thread` | Dedicated OS thread with own runtime | Long-running services, isolation from main runtime | Higher memory overhead per GenServer |
29+ ///
30+ /// **Note**: All backends use async internally. For fully synchronous code without any async
31+ /// runtime, use [`threads::GenServer`](crate::threads::GenServer) instead.
2932///
3033/// # Examples
3134///
3235/// ```ignore
3336/// // For typical async workloads (HTTP handlers, database queries)
34- /// let handle = MyServer::new().start(Backend::Async );
37+ /// let handle = MyServer::new().start();
3538///
3639/// // For occasional blocking operations (file reads, external commands)
37- /// let handle = MyServer::new().start (Backend::Blocking);
40+ /// let handle = MyServer::new().start_with_backend (Backend::Blocking);
3841///
3942/// // For CPU-intensive or permanently blocking services
40- /// let handle = MyServer::new().start (Backend::Thread);
43+ /// let handle = MyServer::new().start_with_backend (Backend::Thread);
4144/// ```
4245///
4346/// # When to Use Each Backend
@@ -53,9 +56,10 @@ const DEFAULT_CALL_TIMEOUT: Duration = Duration::from_secs(5);
5356/// - **Avoid when**: You need guaranteed thread availability or long-running blocks
5457///
5558/// ## `Backend::Thread`
56- /// - **Advantages**: Complete isolation, no interference with async runtime
57- /// - **Use when**: Long-running blocking work, singleton services, CPU-bound tasks
58- /// - **Avoid when**: You need many GenServers (each gets its own OS thread)
59+ /// - **Advantages**: Isolated from main runtime, dedicated thread won't affect other tasks
60+ /// - **Use when**: Long-running singleton services that shouldn't share the main runtime
61+ /// - **Avoid when**: You need many GenServers (each gets its own OS thread + runtime)
62+ /// - **Note**: Still uses async internally (own runtime). For sync code, use `threads::GenServer`
5963#[ derive( Debug , Clone , Copy , Default , PartialEq , Eq ) ]
6064pub enum Backend {
6165 /// Run on tokio async runtime (default).
@@ -81,16 +85,19 @@ pub enum Backend {
8185 /// limit of 512 threads. If the pool is exhausted, new blocking tasks wait.
8286 Blocking ,
8387
84- /// Run on a dedicated OS thread.
88+ /// Run on a dedicated OS thread with its own async runtime .
8589 ///
8690 /// Use for GenServers that:
87- /// - Block indefinitely or for long periods
88- /// - Need guaranteed thread availability
89- /// - Should not compete with other blocking tasks
90- /// - Run CPU-intensive workloads
91+ /// - Need isolation from the main tokio runtime
92+ /// - Are long-running singleton services
93+ /// - Should not compete with other tasks for runtime resources
94+ ///
95+ /// Each GenServer gets its own thread with a separate tokio runtime,
96+ /// providing isolation from other async tasks. Higher memory overhead
97+ /// (~2MB stack per thread plus runtime overhead).
9198 ///
92- /// Each GenServer gets its own thread, providing complete isolation from
93- /// the async runtime. Higher memory overhead (~2MB stack per thread ).
99+ /// **Note**: This still uses async internally. For fully synchronous code
100+ /// without any async runtime, use [`threads::GenServer`](crate::threads::GenServer ).
94101 Thread ,
95102}
96103
@@ -797,7 +804,7 @@ mod tests {
797804 pub fn backend_async_handles_call_and_cast ( ) {
798805 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
799806 runtime. block_on ( async move {
800- let mut counter = Counter { count : 0 } . start ( Backend :: Async ) ;
807+ let mut counter = Counter { count : 0 } . start ( ) ;
801808
802809 // Test call
803810 let result = counter. call ( CounterCall :: Get ) . await . unwrap ( ) ;
@@ -823,7 +830,7 @@ mod tests {
823830 pub fn backend_blocking_handles_call_and_cast ( ) {
824831 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
825832 runtime. block_on ( async move {
826- let mut counter = Counter { count : 0 } . start ( Backend :: Blocking ) ;
833+ let mut counter = Counter { count : 0 } . start_with_backend ( Backend :: Blocking ) ;
827834
828835 // Test call
829836 let result = counter. call ( CounterCall :: Get ) . await . unwrap ( ) ;
@@ -849,7 +856,7 @@ mod tests {
849856 pub fn backend_thread_handles_call_and_cast ( ) {
850857 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
851858 runtime. block_on ( async move {
852- let mut counter = Counter { count : 0 } . start ( Backend :: Thread ) ;
859+ let mut counter = Counter { count : 0 } . start_with_backend ( Backend :: Thread ) ;
853860
854861 // Test call
855862 let result = counter. call ( CounterCall :: Get ) . await . unwrap ( ) ;
@@ -876,9 +883,9 @@ mod tests {
876883 // Similar to badly_behaved_thread but using Backend::Thread
877884 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
878885 runtime. block_on ( async move {
879- let mut badboy = BadlyBehavedTask . start ( Backend :: Thread ) ;
886+ let mut badboy = BadlyBehavedTask . start_with_backend ( Backend :: Thread ) ;
880887 let _ = badboy. cast ( Unused ) . await ;
881- let mut goodboy = WellBehavedTask { count : 0 } . start ( ASYNC ) ;
888+ let mut goodboy = WellBehavedTask { count : 0 } . start ( ) ;
882889 let _ = goodboy. cast ( Unused ) . await ;
883890 rt:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
884891 let count = goodboy. call ( InMessage :: GetCount ) . await . unwrap ( ) ;
@@ -898,9 +905,9 @@ mod tests {
898905 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
899906 runtime. block_on ( async move {
900907 // Start counters on all three backends
901- let mut async_counter = Counter { count : 0 } . start ( Backend :: Async ) ;
902- let mut blocking_counter = Counter { count : 100 } . start ( Backend :: Blocking ) ;
903- let mut thread_counter = Counter { count : 200 } . start ( Backend :: Thread ) ;
908+ let mut async_counter = Counter { count : 0 } . start ( ) ;
909+ let mut blocking_counter = Counter { count : 100 } . start_with_backend ( Backend :: Blocking ) ;
910+ let mut thread_counter = Counter { count : 200 } . start_with_backend ( Backend :: Thread ) ;
904911
905912 // Increment each
906913 async_counter. call ( CounterCall :: Increment ) . await . unwrap ( ) ;
@@ -928,7 +935,7 @@ mod tests {
928935 let runtime = rt:: Runtime :: new ( ) . unwrap ( ) ;
929936 runtime. block_on ( async move {
930937 // Using Backend::default() should work the same as Backend::Async
931- let mut counter = Counter { count : 42 } . start ( Backend :: default ( ) ) ;
938+ let mut counter = Counter { count : 42 } . start ( ) ;
932939
933940 let result = counter. call ( CounterCall :: Get ) . await . unwrap ( ) ;
934941 assert_eq ! ( result, 42 ) ;
0 commit comments