#daemon #engine #ipc #unix #helper #package

bin+lib daemon-engine

A helper package for writing unix rust daemons with IPC based clients

7 unstable releases (3 breaking)

0.4.0 Jan 6, 2019
0.3.3 Dec 31, 2018
0.3.1 Nov 5, 2018
0.2.0 Oct 31, 2018
0.1.0 Aug 15, 2018
Download history 5/week @ 2018-10-12 22/week @ 2018-10-19 1/week @ 2018-10-26 21/week @ 2018-11-02 49/week @ 2018-11-09 30/week @ 2018-11-16 6/week @ 2018-11-23 37/week @ 2018-11-30 9/week @ 2018-12-07 6/week @ 2018-12-14 27/week @ 2018-12-21 15/week @ 2018-12-28 17/week @ 2019-01-04

83 downloads per month

MIT/Apache

48KB
853 lines

Rust Daemon

A library to simplify communication with daemons in rust, with the goal of hiding as much of the complexity of / minimizing the effort required to use tokio as much as possible.

This consists of a higher-level generic server and connection object to provide typed communication between components, implemented using tokio using codecs. This is designed to support arbitrary stream types, and both types have been implemented over TCPStream and UnixStream for convenience. If you find any other useful stream types to wrap, please open an issue or a PR!

A generic example codec is provided using serde and serde_json to establish a type-safe json interface for client-daemon communication, when using this codec the ENC and DEC types must implement serde Serialize and Deserialize traits, these may be implemented using serde_derive. It is intended that additional codecs will be added as they are required.

Status

GitHub tag Build Status Crates.io Docs.rs

Open Issues

Usage

See src/examples/server.rs and src/examples/connection.rs for an example server and client implementing a simple key-value store.

You can build these examples with cargo build --features examples, run the server with ./targets/debug/rustd-server and interact using ./targets/debug/rustd-client. rustd-client -k KEY fetches the value for a given key, rustd-client -k KEY -v VALUE sets the value of the given key, and rustd-client --help will display available arguments.

Client

extern crate daemon_engine;
use daemon_engine::Connection;

...

// Create client instance
let stream = UnixStream::connect(path.clone()).wait().unwrap();
let client = Connection::<_, JsonCodec<Test, Test, JsonError>>::new(stream);

// Split RX and TX
let (tx, rx) = client.split();

// Send something (remember to .wait())
tx.send(Request::Something).wait().unwrap();

// Receive something (also remember to wait)
rx.map(|resp| -> Result<(), DaemonError> {
    println!("Response: {:?}", resp);
    Ok(())
}).wait().next();

Server

extern crate tokio;
use tokio::prelude::*;
use tokio::{run, spawn};

extern crate daemon_engine;
use daemon_engine::Server;
use daemon_engine::codecs::json::{JsonCodec, JsonError};

...

let server_handle = future::lazy(move || {
    // Create server instance using the JSON codec, this must be executed from within a tokio context
    let mut server = Server::<_, JsonCodec<Request, Response, JsonError>>::new_unix(&server_path).unwrap();

    // Handle requests from clients
    s.incoming().unwrap().for_each(move |r| {
        println!("Request: {:?}", r.data());
        let data = r.data();
        match data {
            ...
            _ => {
                r.send(Response::Something(v.to_string()))
            }
        // Remember you have to .wait or otherwise prompt for send to occur
        }.wait().unwrap();
        Ok(())
    }).map_err(|_e| ());

    // do more stuff
    ...

    // Close the server when you're done
    s.close();

    Ok(())
});

// Create server task
tokio::run(server_handle);

If you have any questions, comments, or suggestions, feel free to open an issue or a pull request.

Dependencies

~6.5MB
~111K SLoC