tcrm_task/lib.rs
1//! # tcrm-task
2//!
3//! A process execution library.
4//!
5//! ## Features
6//!
7//! - **Real-time Events**: Monitor process output, state changes, and lifecycle events
8//! - **Timeout**: Configurable process execution timeouts
9//! - **Ready Indicators**: Detect when long-running processes are ready to accept requests via output matching
10//! - **Process control**: Cross-platform signal sending and process control
11//! - **Process Groups**: Optional feature for managing all child processes via groups/job objects
12//!
13//! ## Quick Start
14//!
15//! ```rust
16//! use tcrm_task::tasks::{config::TaskConfig, tokio::executor::TaskExecutor};
17//! use tokio::sync::mpsc;
18//!
19//! #[tokio::main]
20//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21//! // Create and validate configuration
22//! #[cfg(windows)]
23//! let config = TaskConfig::new("cmd").args(["/C", "echo", "Hello, World!"]);
24//! #[cfg(unix)]
25//! let config = TaskConfig::new("echo").args(["Hello, World!"]);
26//!
27//! // Create executor and event channel
28//! let (tx, mut rx) = mpsc::channel(100);
29//! let mut executor = TaskExecutor::new(config, tx);
30//!
31//! // Spawns a new asynchronous task
32//! executor.coordinate_start().await?;
33//!
34//! // Process events
35//! while let Some(envelope) = rx.recv().await {
36//! match envelope.event {
37//! tcrm_task::tasks::event::TaskEvent::Started { process_id, .. } => {
38//! println!("Process started with ID: {}", process_id);
39//! }
40//! tcrm_task::tasks::event::TaskEvent::Output { line, .. } => {
41//! println!("Output: {}", line);
42//! }
43//! tcrm_task::tasks::event::TaskEvent::Stopped { exit_code, .. } => {
44//! println!("Process finished with exit code: {:?}", exit_code);
45//! break;
46//! }
47//! _ => {}
48//! }
49//! }
50//!
51//! Ok(())
52//! }
53//! ```
54//!
55//! ### Long-running Process with Ready Indicator
56//!
57//! ```rust
58//! use tcrm_task::tasks::{
59//! config::{TaskConfig, StreamSource},
60//! tokio::executor::TaskExecutor,
61//! event::TaskEvent
62//! };
63//! use tokio::sync::mpsc;
64//!
65//! #[tokio::main]
66//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
67//! #[cfg(windows)]
68//! let config = TaskConfig::new("cmd")
69//! .args(["/C", "echo", "Server listening on port 3000"])
70//! .ready_indicator("Server listening")
71//! .ready_indicator_source(StreamSource::Stdout)
72//! .timeout_ms(30000);
73//!
74//! #[cfg(unix)]
75//! let config = TaskConfig::new("echo")
76//! .args(["Server listening on port 3000"])
77//! .ready_indicator("Server listening")
78//! .ready_indicator_source(StreamSource::Stdout)
79//! .timeout_ms(30000);
80//!
81//! let (tx, mut rx) = mpsc::channel(100);
82//! let mut executor = TaskExecutor::new(config, tx);
83//!
84//! executor.coordinate_start().await?;
85//!
86//! // Wait for ready event
87//! while let Some(envelope) = rx.recv().await {
88//! match envelope.event {
89//! TaskEvent::Ready => {
90//! println!("Server is ready for requests!");
91//! break;
92//! }
93//! TaskEvent::Output { line, .. } => {
94//! println!("Server log: {}", line);
95//! }
96//! TaskEvent::Error { error } => {
97//! eprintln!("Error: {}", error);
98//! break;
99//! }
100//! _ => {}
101//! }
102//! }
103//!
104//! Ok(())
105//! }
106//! ```
107//!
108//! ### Process Control and Termination
109//!
110//! ```rust
111//! use tcrm_task::tasks::{
112//! config::TaskConfig,
113//! tokio::executor::TaskExecutor,
114//! control::TaskControl,
115//! event::TaskTerminateReason
116//! };
117//! use tokio::sync::mpsc;
118//!
119//! #[tokio::main]
120//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
121//! #[cfg(windows)]
122//! let config = TaskConfig::new("cmd")
123//! .args(["/C", "timeout", "/t", "10"])
124//! .timeout_ms(5000); // 5 second timeout
125//!
126//! #[cfg(unix)]
127//! let config = TaskConfig::new("sleep")
128//! .args(["10"])
129//! .timeout_ms(5000); // 5 second timeout
130//!
131//! let (tx, mut rx) = mpsc::channel(100);
132//! let mut executor = TaskExecutor::new(config, tx);
133//!
134//! executor.coordinate_start().await?;
135//!
136//! // Terminate after 2 seconds
137//! tokio::spawn(async move {
138//! tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
139//! let _ = executor.terminate_task(TaskTerminateReason::UserRequested);
140//! });
141//!
142//! // Process events until completion
143//! while let Some(envelope) = rx.recv().await {
144//! match envelope.event {
145//! tcrm_task::tasks::event::TaskEvent::Stopped { reason, .. } => {
146//! println!("Process stopped: {:?}", reason);
147//! break;
148//! }
149//! _ => {}
150//! }
151//! }
152//!
153//! Ok(())
154//! }
155//! ```
156//!
157//! ## Features
158//!
159//! - `tokio`: Async runtime support (default)
160//! - `tokio-coordinate`: Full coordination module (default)
161//! - `process-group`: Process group management (default)
162//! - `signal`: Sending signals to processes
163//! - `serde`: Serialization support for all types
164//! - `flatbuffers`: High-performance serialization
165//! - `tracing`: Structured logging integration
166
167#[cfg(feature = "flatbuffers")]
168pub mod flatbuffers;
169pub mod tasks;