Writing a daemon

DarkFi consists of many seperate daemons communicating with each other. To run the p2p network, we'll need to implement our own daemon. So we'll start building dchat by creating a daemon that we call dchatd.

To do this, we'll make use of a DarkFi macro called async_daemonize.

async_daemonizeis the standard way of daemonizing darkfi binaries. It implements TOML config file configuration, argument parsing and a multithreaded async executor that can be passed into the given function.

We use async_daemonize as follows:

use darkfi::{async_daemonize, cli_desc, Result};
use smol::stream::StreamExt;
use structopt_toml::{serde::Deserialize, structopt::StructOpt, StructOptToml};

const CONFIG_FILE: &str = "dchatd_config.toml";
const CONFIG_FILE_CONTENTS: &str = include_str!("../dchatd_config.toml");

#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
#[serde(default)]
#[structopt(name = "daemond", about = cli_desc!())]
struct Args {
    #[structopt(short, long)]
    /// Configuration file to use
    config: Option<String>,

    #[structopt(short, long)]
    /// Set log file to ouput into
    log: Option<String>,

    #[structopt(short, parse(from_occurrences))]
    /// Increase verbosity (-vvv supported)
    verbose: u8,
}

async_daemonize!(realmain);
async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
    println!("Hello, world!");
    Ok(())
}

Behind the scenes, async_daemonize uses structopt and structopt_toml crates to build command line arguments as a struct called Args. It spins up a async executor using parallel threads, and implements signal handling to properly terminate the daemon on receipt of a stop signal.

async_daemonize allow us to spawn the config data we specify at CONFIG_FILE_CONTENTS into a directory either specified using the command-line flag --config, or in the default darkfi config directory.

async_daemonize also implements logging that will output different levels of debug info to the terminal, or to both the terminal and a log file if a log file is specified.