-
Notifications
You must be signed in to change notification settings - Fork 1
/
pipe.rs
56 lines (49 loc) · 1.79 KB
/
pipe.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/// Launches a subprocess and reads its output line by line. Useful to connect RoboPLC with 3rd
/// party software which can not be embedded.
use roboplc::controller::prelude::*;
use roboplc::io::pipe::{self, Pipe};
use roboplc::{prelude::*, Error};
const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
type Message = ();
type Variables = ();
#[derive(WorkerOpts)]
#[worker_opts(cpu = 0, priority = 50, scheduling = "fifo", blocking = true)]
struct Worker1 {
reader: pipe::Reader,
}
impl Worker<Message, Variables> for Worker1 {
fn run(&mut self, _context: &Context<Message, Variables>) -> WResult {
loop {
let line = self.reader.line()?;
println!("Worker1: {}", line.trim_end());
}
}
}
#[derive(WorkerOpts)]
#[worker_opts(cpu = 0, priority = 50, scheduling = "fifo", blocking = true)]
struct PipeRunner {
pipe: Pipe,
}
impl Worker<Message, Variables> for PipeRunner {
/// The piped subprocess needs to be run by a worker. The subprocess inherits the scheduling
/// policy and priority of the worker.
fn run(&mut self, _context: &Context<Message, Variables>) -> WResult {
self.pipe.run();
Err(Error::failed("pipe exited").into())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
roboplc::setup_panic();
roboplc::configure_logger(roboplc::LevelFilter::Info);
if !roboplc::is_production() {
roboplc::thread_rt::set_simulated();
}
roboplc::thread_rt::prealloc_heap(10_000_000)?;
let mut controller = Controller::<Message, Variables>::new();
let (pipe, reader) = Pipe::new("/path/to/subprogram");
controller.spawn_worker(Worker1 { reader })?;
controller.spawn_worker(PipeRunner { pipe })?;
controller.register_signals(SHUTDOWN_TIMEOUT)?;
controller.block();
Ok(())
}