17 releases

0.6.1 Sep 13, 2024
0.6.0 Mar 14, 2024
0.5.2 Apr 13, 2022
0.5.1 Jan 6, 2022
0.2.0 Sep 10, 2018

#186 in Unix APIs

Download history 214/week @ 2024-08-23 181/week @ 2024-08-30 127/week @ 2024-09-06 253/week @ 2024-09-13 119/week @ 2024-09-20 348/week @ 2024-09-27 341/week @ 2024-10-04 94/week @ 2024-10-11 225/week @ 2024-10-18 473/week @ 2024-10-25 412/week @ 2024-11-01 434/week @ 2024-11-08 339/week @ 2024-11-15 333/week @ 2024-11-22 553/week @ 2024-11-29 611/week @ 2024-12-06

1,924 downloads per month

MIT/Apache

50KB
1K SLoC

ceviche-rs

Cargo Documentation Build

Service/daemon wrapper. Supports Windows, Linux (systemd) and macOS.


lib.rs:

ceviche is a wrapper to write a service/daemon.

At the moment only Windows services are supported. The Service macro is inspired from the winservice crate.

A service implements a service main function and is generated by invoking the Service! macro. The events are sent to the service over the rx channel.

 enum CustomServiceEvent {}

fn my_service_main(
    rx: mpsc::Receiver<ServiceEvent<CustomServiceEvent>>,
    _tx: mpsc::Sender<ServiceEvent<CustomServiceEvent>>,
    args: Vec<String>,
    standalone_mode: bool) -> u32 {
   loop {
       if let Ok(control_code) = rx.recv() {
           match control_code {
               ServiceEvent::Stop => break,
               _ => (),
           }
       }
   }
   0
}

Service!("Foobar", my_service_main);

The Controller is a helper to create, remove, start or stop the service on the system. ceviche also supports a standalone mode were the service code runs as a normal executable which can be useful for development and debugging.

static SERVICE_NAME: &'static str = "foobar";
static DISPLAY_NAME: &'static str = "FooBar Service";
static DESCRIPTION: &'static str = "This is the FooBar service";

fn main() {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml);
    let matches = app.version(crate_version!()).get_matches();
    let cmd = matches.value_of("cmd").unwrap_or("").to_string();

    let mut controller = Controller::new(SERVICE_NAME, DISPLAY_NAME, DESCRIPTION);

    match cmd.as_str() {
        "create" => controller.create(),
        "delete" => controller.delete(),
        "start" => controller.start(),
        "stop" => controller.stop(),
        "standalone" => {
            let (tx, rx) = mpsc::channel();

            ctrlc::set_handler(move || {
                let _ = tx.send(ServiceEvent::Stop);
            }).expect("Failed to register Ctrl-C handler");

            my_service_main(rx, vec![], true);
        }
        _ => {
            let _result = controller.register(service_main_wrapper);
        }
    }
}

Dependencies

~1.6–10MB
~105K SLoC