at backyard

Color my life with the chaos of trouble.

actix-webで作成したRustのサーバプログラムをデーモン化する

先日書いたこちらのポストのサーバ版的なメモ。

shinshin86.hateblo.jp

上で書いた内容に actix-web をかけ合わせただけの、本当に自分向けのメモの過ぎない。

基本となるサーバコード

まず、基本となるサーバコードがこちら。
なお、ここに書いた基本的なサーバコードは actix-web 内のgetting startedにあるコードである。

actix.rs

use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
    HttpResponse::Ok().body(req_body)
}

async fn manual_hello() -> impl Responder {
    HttpResponse::Ok().body("Hey there!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(echo)
            .route("/hey", web::get().to(manual_hello))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

これで

cargo run

すると、サーバプロセスが立ち上がる。

Ctrl + C などを押すと、処理が停止するという形となる。

これをデーモン化したい。

actix-webのサーバプロセスをデーモン化したもの

上のコードをデーモン化したものがこちら。

extern crate daemonize;
use std::fs::File;
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
use daemonize::Daemonize;

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
    HttpResponse::Ok().body(req_body)
}

async fn manual_hello() -> impl Responder {
    HttpResponse::Ok().body("Hey there!")
}

#[actix_web::main]
async fn start_server() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(echo)
            .route("/hey", web::get().to(manual_hello))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

fn main() {
    let stdout = File::create("./daemon-dir/daemon.out").unwrap();
    let stderr = File::create("./daemon-dir/daemon.err").unwrap();

    let daemonize = Daemonize::new()
        .pid_file("./daemon-dir/test.pid")
        .working_directory("./daemon-dir")
        .stdout(stdout)
        .stderr(stderr)
        .exit_action(|| println!("Executed before master process exits"))
        .privileged_action(|| return "Executed before drop privileges");

    match daemonize.start() {
        Ok(v) => {
            println!("{:?}", v);
            println!("Success, daemonized");
            start_server().unwrap();
        },
        Err(e) => eprintln!("Error, {}", e)
    }
}

サーバの起動処理を start_server という関数に閉じ込めて、デーモンがスタートした際にそちらを実行するように変更した。

他の記述については以前書いたポストとほとんど同じである。

これで cargo runすると処理が離れて、サーバプロセスがデーモン化(常駐化)する。

プロセスを止める場合は、対象のプロセスIDに対して kill コマンドを打つ。

メモ書きは以上。