thread_share/
enhanced.rs

1//! # Enhanced Module - EnhancedThreadShare<T>
2//!
3//! This module provides `EnhancedThreadShare<T>`, a powerful extension of `ThreadShare<T>`
4//! that adds automatic thread management capabilities.
5//!
6//! ## 🚀 Overview
7//!
8//! `EnhancedThreadShare<T>` eliminates the need for manual thread management by providing:
9//!
10//! - **Automatic Thread Spawning**: Spawn threads with a single method call
11//! - **Built-in Thread Tracking**: Monitor active thread count and status
12//! - **Automatic Thread Joining**: Wait for all threads to complete with `join_all()`
13//! - **Thread Naming**: Give meaningful names to threads for debugging
14//! - **All ThreadShare Features**: Inherits all capabilities from `ThreadShare<T>`
15//!
16//! ## Key Benefits
17//!
18//! ### 🎯 Simplified Thread Management
19//! ```rust
20//! // Old way: Manual thread management
21//! use thread_share::share;
22//! use std::thread;
23//!
24//! let data = share!(vec![1, 2, 3]);
25//! let clone1 = data.clone();
26//! let clone2 = data.clone();
27//!
28//! let handle1 = thread::spawn(move || { /* logic */ });
29//! let handle2 = thread::spawn(move || { /* logic */ });
30//!
31//! handle1.join().expect("Failed to join");
32//! handle2.join().expect("Failed to join");
33//!
34//! // New way: Enhanced thread management
35//! use thread_share::enhanced_share;
36//!
37//! let enhanced = enhanced_share!(vec![1, 2, 3]);
38//!
39//! enhanced.spawn("worker1", |data| { /* logic */ });
40//! enhanced.spawn("worker2", |data| { /* logic */ });
41//!
42//! enhanced.join_all().expect("Failed to join");
43//! ```
44//!
45//! ### 📊 Real-time Monitoring
46//! ```rust
47//! use thread_share::enhanced_share;
48//!
49//! let enhanced = enhanced_share!(vec![1, 2, 3]);
50//!
51//! enhanced.spawn("processor", |data| { /* logic */ });
52//! enhanced.spawn("validator", |data| { /* logic */ });
53//!
54//! println!("Active threads: {}", enhanced.active_threads());
55//!
56//! // Wait for completion
57//! enhanced.join_all().expect("Failed to join");
58//!
59//! assert!(enhanced.is_complete());
60//! ```
61//!
62//! ## Architecture
63//!
64//! `EnhancedThreadShare<T>` wraps a `ThreadShare<T>` and adds:
65//!
66//! - **`inner: ThreadShare<T>`** - The underlying shared data
67//! - **`threads: Arc<Mutex<HashMap<String, JoinHandle<()>>>>`** - Thread tracking
68//!
69//! ## Thread Lifecycle
70//!
71//! 1. **Creation**: `EnhancedThreadShare::new(data)` or `enhanced_share!(data)`
72//! 2. **Spawning**: `enhanced.spawn(name, function)` creates named threads
73//! 3. **Execution**: Threads run with access to shared data
74//! 4. **Monitoring**: Track active threads with `active_threads()`
75//! 5. **Completion**: Wait for all threads with `join_all()`
76//!
77//! ## Example Usage
78//!
79//! ### Basic Thread Management
80//! ```rust
81//! use thread_share::{enhanced_share, spawn_workers};
82//!
83//! let data = enhanced_share!(vec![1, 2, 3]);
84//!
85//! // Spawn individual threads
86//! data.spawn("sorter", |data| {
87//!     data.update(|v| v.sort());
88//! });
89//!
90//! data.spawn("validator", |data| {
91//!     assert!(data.get().is_sorted());
92//! });
93//!
94//! // Wait for completion
95//! data.join_all().expect("Failed to join");
96//! ```
97//!
98//! ### Using Macros
99//! ```rust
100//! use thread_share::share;
101//!
102//! let data = share!(String::from("Hello"));
103//! let clone = data.clone();
104//!
105//! // Spawn a simple thread
106//! std::thread::spawn(move || {
107//!     clone.update(|s| s.push_str(" World"));
108//! });
109//!
110//! // Wait a bit and check result
111//! std::thread::sleep(std::time::Duration::from_millis(100));
112//! println!("Updated: {}", data.get());
113//! ```
114//!
115//! ### Real-world Example
116//! ```rust
117//! use thread_share::share;
118//! use std::time::Duration;
119//!
120//! #[derive(Clone)]
121//! struct Server {
122//!     port: u16,
123//!     is_running: bool,
124//!     connections: u32,
125//! }
126//!
127//! let server = share!(Server {
128//!     port: 8080,
129//!     is_running: false,
130//!     connections: 0,
131//! });
132//!
133//! let server_clone = server.clone();
134//!
135//! // Spawn a simple server thread
136//! std::thread::spawn(move || {
137//!     server_clone.update(|s| {
138//!         s.is_running = true;
139//!         s.connections = 5;
140//!     });
141//! });
142//!
143//! // Wait a bit and check result
144//! std::thread::sleep(Duration::from_millis(100));
145//! let final_state = server.get();
146//! println!("Server running: {}, connections: {}", final_state.is_running, final_state.connections);
147//! ```
148//!
149//! ## Performance Characteristics
150//!
151//! - **Thread Spawning**: Minimal overhead over standard `thread::spawn`
152//! - **Thread Tracking**: Constant-time operations for thread management
153//! - **Memory Usage**: Small overhead for thread tracking structures
154//! - **Scalability**: Efficient for up to hundreds of threads
155//!
156//! ## Best Practices
157//!
158//! 1. **Use descriptive thread names** for easier debugging
159//! 2. **Keep thread functions focused** on single responsibilities
160//! 3. **Always call `join_all()`** to ensure proper cleanup
161//! 4. **Monitor thread count** with `active_threads()` for debugging
162//! 5. **Handle errors gracefully** from `join_all()` and `spawn()`
163//!
164//! ## Error Handling
165//!
166//! ```rust
167//! use thread_share::share;
168//!
169//! let data = share!(0);
170//! let clone = data.clone();
171//!
172//! // Spawn thread with error handling
173//! let handle = std::thread::spawn(move || {
174//!     clone.update(|x| *x = *x + 1);
175//! });
176//!
177//! // Handle join errors
178//! if let Err(e) = handle.join() {
179//!     eprintln!("Thread execution failed: {:?}", e);
180//! }
181//! ```
182//!
183//! ## Thread Safety
184//!
185//! `EnhancedThreadShare<T>` automatically implements `Send` and `Sync` traits
186//! when `T` implements them, making it safe to use across thread boundaries.
187//!
188//! ## Integration with Macros
189//!
190//! This module works seamlessly with the library's macros:
191//!
192//! - **`enhanced_share!`** - Creates `EnhancedThreadShare<T>` instances
193//! - **`spawn_workers!`** - Spawns multiple threads with single macro call
194//!
195//! ## Comparison with Manual Thread Management
196//!
197//! | Aspect | Manual Management | EnhancedThreadShare |
198//! |--------|-------------------|-------------------|
199//! | **Thread Creation** | `thread::spawn()` calls | `enhanced.spawn()` |
200//! | **Thread Tracking** | Manual `JoinHandle` storage | Automatic tracking |
201//! | **Thread Joining** | Manual `join()` calls | `join_all()` |
202//! | **Error Handling** | Per-thread error handling | Centralized error handling |
203//! | **Debugging** | No thread identification | Named threads |
204//! | **Code Complexity** | High | Low |
205
206use crate::core::ThreadShare;
207use std::collections::HashMap;
208use std::sync::{Arc, Mutex};
209use std::thread;
210
211/// Enhanced ThreadShare with built-in thread management
212///
213/// `EnhancedThreadShare<T>` extends `ThreadShare<T>` with automatic thread management
214/// capabilities, eliminating the need for manual thread spawning and joining.
215///
216/// ## Key Features
217///
218/// - **Automatic Thread Spawning**: Spawn threads with a single method call
219/// - **Built-in Thread Tracking**: Monitor active thread count and status
220/// - **Automatic Thread Joining**: Wait for all threads to complete with `join_all()`
221/// - **Thread Naming**: Give meaningful names to threads for debugging
222/// - **All ThreadShare Features**: Inherits all capabilities from `ThreadShare<T>`
223///
224/// ## Example
225///
226/// ```rust
227/// use thread_share::{enhanced_share, spawn_workers};
228///
229/// let data = enhanced_share!(vec![1, 2, 3]);
230///
231/// // Spawn individual threads
232/// data.spawn("sorter", |data| {
233///     data.update(|v| v.sort());
234/// });
235///
236/// data.spawn("validator", |data| {
237///     assert!(data.get().is_sorted());
238/// });
239///
240/// // Wait for completion
241/// data.join_all().expect("Failed to join");
242/// ```
243///
244/// ## Thread Lifecycle
245///
246/// 1. **Creation**: `EnhancedThreadShare::new(data)` or `enhanced_share!(data)`
247/// 2. **Spawning**: `enhanced.spawn(name, function)` creates named threads
248/// 3. **Execution**: Threads run with access to shared data
249/// 4. **Monitoring**: Track active threads with `active_threads()`
250/// 5. **Completion**: Wait for all threads with `join_all()`
251///
252/// ## Performance
253///
254/// - **Thread Spawning**: Minimal overhead over standard `thread::spawn`
255/// - **Thread Tracking**: Constant-time operations for thread management
256/// - **Memory Usage**: Small overhead for thread tracking structures
257/// - **Scalability**: Efficient for up to hundreds of threads
258pub struct EnhancedThreadShare<T> {
259    inner: ThreadShare<T>,
260    threads: Arc<Mutex<HashMap<String, thread::JoinHandle<()>>>>,
261}
262
263impl<T> EnhancedThreadShare<T> {
264    /// Creates a new EnhancedThreadShare
265    ///
266    /// This method creates a new `EnhancedThreadShare<T>` instance with the provided data.
267    /// The data is wrapped in a `ThreadShare<T>` for safe sharing between threads.
268    ///
269    /// ## Arguments
270    ///
271    /// * `data` - The initial data to share between threads
272    ///
273    /// ## Returns
274    ///
275    /// A new `EnhancedThreadShare<T>` instance.
276    ///
277    /// ## Example
278    ///
279    /// ```rust
280    /// use thread_share::EnhancedThreadShare;
281    ///
282    /// let enhanced = EnhancedThreadShare::new(0);
283    /// let enhanced = EnhancedThreadShare::new(String::from("Hello"));
284    /// let enhanced = EnhancedThreadShare::new(vec![1, 2, 3]);
285    /// ```
286    pub fn new(data: T) -> Self {
287        Self {
288            inner: ThreadShare::new(data),
289            threads: Arc::new(Mutex::new(HashMap::new())),
290        }
291    }
292
293    /// Spawns a thread with access to this shared data
294    ///
295    /// This method creates a new thread with the given name and function.
296    /// The thread receives a clone of the shared data and can safely modify it.
297    ///
298    /// ## Arguments
299    ///
300    /// * `name` - A descriptive name for the thread (useful for debugging)
301    /// * `f` - A function that receives `ThreadShare<T>` and performs the thread's work
302    ///
303    /// ## Requirements
304    ///
305    /// The function `F` must:
306    /// - Implement `FnOnce(ThreadShare<T>)` - called once with shared data
307    /// - Implement `Send` - safe to send across thread boundaries
308    /// - Have `'static` lifetime - no borrowed references
309    ///
310    /// The type `T` must implement `Send + Sync + 'static`.
311    ///
312    /// ## Returns
313    ///
314    /// `Ok(())` on success, `Err(String)` if thread spawning fails.
315    ///
316    /// ## Example
317    ///
318    /// ```rust
319    /// use thread_share::EnhancedThreadShare;
320    ///
321    /// let enhanced = EnhancedThreadShare::new(0);
322    ///
323    /// // Spawn a worker thread
324    /// enhanced.spawn("worker", |data| {
325    ///     for _ in 0..100 {
326    ///         data.update(|x| *x += 1);
327    ///         std::thread::sleep(std::time::Duration::from_millis(10));
328    ///     }
329    /// }).expect("Failed to spawn worker");
330    ///
331    /// // Spawn a monitor thread
332    /// enhanced.spawn("monitor", |data| {
333    ///     for _ in 0..10 {
334    ///         std::thread::sleep(std::time::Duration::from_millis(100));
335    ///         println!("Current value: {}", data.get());
336    ///     }
337    /// }).expect("Failed to spawn monitor");
338    /// ```
339    pub fn spawn<F>(&self, name: &str, f: F) -> Result<(), String>
340    where
341        F: FnOnce(ThreadShare<T>) + Send + 'static,
342        T: Send + Sync + 'static,
343    {
344        let thread_name = name.to_string();
345        let thread_data = self.inner.clone();
346
347        let handle = thread::spawn(move || {
348            f(thread_data);
349        });
350
351        self.threads.lock().unwrap().insert(thread_name, handle);
352        Ok(())
353    }
354
355    /// Spawns multiple threads with different names and functions
356    ///
357    /// This method spawns multiple threads from a vector of configurations.
358    /// Each configuration contains a thread name and a function.
359    ///
360    /// ## Arguments
361    ///
362    /// * `thread_configs` - Vector of `(name, function)` tuples
363    ///
364    /// ## Requirements
365    ///
366    /// The function `F` must implement `Clone` in addition to the standard requirements.
367    ///
368    /// ## Returns
369    ///
370    /// `Ok(())` on success, `Err(String)` if any thread spawning fails.
371    /// ```
372    pub fn spawn_multiple<F>(&self, thread_configs: Vec<(&str, F)>) -> Result<(), String>
373    where
374        F: FnOnce(ThreadShare<T>) + Send + Clone + 'static,
375        T: Send + Sync + 'static,
376    {
377        for (name, func) in thread_configs {
378            self.spawn(name, func)?;
379        }
380        Ok(())
381    }
382
383    /// Spawns multiple threads with boxed closures
384    ///
385    /// This method spawns multiple threads using boxed closures, which allows
386    /// for different function types in the same vector.
387    ///
388    /// ## Arguments
389    ///
390    /// * `thread_configs` - Vector of `(name, boxed_function)` tuples
391    ///
392    /// ## Returns
393    ///
394    /// `Ok(())` on success, `Err(String)` if any thread spawning fails.
395    ///
396    /// ## Example
397    ///
398    /// ```rust
399    /// use thread_share::EnhancedThreadShare;
400    ///
401    /// let enhanced = EnhancedThreadShare::new(0);
402    ///
403    /// let configs = vec![
404    ///     ("worker1", Box::new(|data: thread_share::ThreadShare<i32>| { data.update(|x| *x = *x + 1); }) as Box<dyn FnOnce(thread_share::ThreadShare<i32>) + Send>),
405    ///     ("worker2", Box::new(|data: thread_share::ThreadShare<i32>| { data.update(|x| *x = *x + 2); }) as Box<dyn FnOnce(thread_share::ThreadShare<i32>) + Send>),
406    /// ];
407    ///
408    /// enhanced.spawn_multiple_boxed(configs).expect("Failed to spawn threads");
409    /// ```
410    pub fn spawn_multiple_boxed(
411        &self,
412        thread_configs: Vec<(&str, Box<dyn FnOnce(ThreadShare<T>) + Send>)>,
413    ) -> Result<(), String>
414    where
415        T: Send + Sync + 'static,
416    {
417        for (name, func) in thread_configs {
418            let thread_data = self.inner.clone();
419            let handle = thread::spawn(move || {
420                func(thread_data);
421            });
422            self.threads
423                .lock()
424                .unwrap()
425                .insert(name.to_string(), handle);
426        }
427        Ok(())
428    }
429
430    /// Waits for all spawned threads to complete
431    ///
432    /// This method blocks until all spawned threads have finished execution.
433    /// It joins each thread and returns an error if any thread panics.
434    ///
435    /// ## Returns
436    ///
437    /// `Ok(())` when all threads complete successfully, `Err(String)` if any thread fails.
438    ///
439    /// ## Example
440    ///
441    /// ```rust
442    /// use thread_share::EnhancedThreadShare;
443    ///
444    /// let enhanced = EnhancedThreadShare::new(0);
445    ///
446    /// enhanced.spawn("worker", |data| {
447    ///     data.update(|x| *x = *x + 100);
448    /// }).expect("Failed to spawn worker");
449    ///
450    /// // Wait for all threads to complete
451    /// enhanced.join_all().expect("Thread execution failed");
452    ///
453    /// // Now safe to access the final result
454    /// assert_eq!(enhanced.get(), 100);
455    /// ```
456    pub fn join_all(&self) -> Result<(), String> {
457        let mut threads = self.threads.lock().unwrap();
458        let thread_handles: Vec<_> = threads.drain().collect();
459        drop(threads);
460
461        for (name, handle) in thread_handles {
462            let result = handle.join();
463            if let Err(e) = result {
464                return Err(format!("Thread '{}' failed: {:?}", name, e));
465            }
466        }
467        Ok(())
468    }
469
470    /// Gets the number of active threads
471    ///
472    /// This method returns the current number of threads that are still running.
473    ///
474    /// ## Returns
475    ///
476    /// The number of active threads.
477    ///
478    /// ## Example
479    ///
480    /// ```rust
481    /// use thread_share::EnhancedThreadShare;
482    /// use std::time::Duration;
483    ///
484    /// let enhanced = EnhancedThreadShare::new(0);
485    ///
486    /// enhanced.spawn("worker", |data| {
487    ///     std::thread::sleep(Duration::from_millis(100));
488    /// }).expect("Failed to spawn worker");
489    ///
490    /// println!("Active threads: {}", enhanced.active_threads()); // Prints: 1
491    ///
492    /// // Wait for completion
493    /// enhanced.join_all().expect("Failed to join");
494    ///
495    /// println!("Active threads: {}", enhanced.active_threads()); // Prints: 0
496    /// ```
497    pub fn active_threads(&self) -> usize {
498        self.threads.lock().unwrap().len()
499    }
500
501    /// Checks if all threads have completed
502    ///
503    /// This method returns `true` if there are no active threads, `false` otherwise.
504    ///
505    /// ## Returns
506    ///
507    /// `true` if all threads have completed, `false` if any threads are still running.
508    ///
509    /// ## Example
510    ///
511    /// ```rust
512    /// use thread_share::EnhancedThreadShare;
513    ///
514    /// let enhanced = EnhancedThreadShare::new(0);
515    ///
516    /// enhanced.spawn("worker", |data| {
517    ///     data.update(|x| *x = *x + 1);
518    /// }).expect("Failed to spawn worker");
519    ///
520    /// assert!(!enhanced.is_complete()); // Thread is still running
521    ///
522    /// enhanced.join_all().expect("Failed to join");
523    ///
524    /// assert!(enhanced.is_complete()); // All threads completed
525    /// ```
526    pub fn is_complete(&self) -> bool {
527        self.threads.lock().unwrap().is_empty()
528    }
529
530    /// Gets a reference to the threads HashMap for external management
531    pub fn get_threads(&self) -> Arc<Mutex<HashMap<String, thread::JoinHandle<()>>>> {
532        self.threads.clone()
533    }
534
535    /// Delegates all ThreadShare methods
536    ///
537    /// Gets a copy of the shared data.
538    ///
539    /// ## Requirements
540    ///
541    /// The type `T` must implement `Clone` trait.
542    ///
543    /// ## Returns
544    ///
545    /// A copy of the current data.
546    ///
547    /// ## Example
548    ///
549    /// ```rust
550    /// use thread_share::EnhancedThreadShare;
551    ///
552    /// let enhanced = EnhancedThreadShare::new(42);
553    /// let value = enhanced.get();
554    /// assert_eq!(value, 42);
555    /// ```
556    pub fn get(&self) -> T
557    where
558        T: Clone,
559    {
560        self.inner.get()
561    }
562
563    /// Sets new data and notifies waiting threads
564    ///
565    /// This method replaces the current data and notifies all threads
566    /// waiting for changes.
567    ///
568    /// ## Arguments
569    ///
570    /// * `new_data` - The new data to set
571    ///
572    /// ## Example
573    ///
574    /// ```rust
575    /// use thread_share::EnhancedThreadShare;
576    ///
577    /// let enhanced = EnhancedThreadShare::new(0);
578    /// enhanced.set(100);
579    /// assert_eq!(enhanced.get(), 100);
580    /// ```
581    pub fn set(&self, new_data: T) {
582        self.inner.set(new_data);
583    }
584
585    pub fn update<F>(&self, f: F)
586    where
587        F: FnOnce(&mut T),
588    {
589        self.inner.update(f);
590    }
591
592    pub fn read<F, R>(&self, f: F) -> R
593    where
594        F: FnOnce(&T) -> R,
595    {
596        self.inner.read(f)
597    }
598
599    pub fn write<F, R>(&self, f: F) -> R
600    where
601        F: FnOnce(&mut T) -> R,
602    {
603        self.inner.write(f)
604    }
605
606    pub fn wait_for_change(&self, timeout: std::time::Duration) -> bool {
607        self.inner.wait_for_change(timeout)
608    }
609
610    pub fn wait_for_change_forever(&self) {
611        self.inner.wait_for_change_forever();
612    }
613
614    pub fn clone(&self) -> Self {
615        Self {
616            inner: self.inner.clone(),
617            threads: Arc::new(Mutex::new(HashMap::new())),
618        }
619    }
620}
621
622impl<T> Clone for EnhancedThreadShare<T> {
623    fn clone(&self) -> Self {
624        self.clone()
625    }
626}
627
628
629
630