5

I'm currently implementing a server using Rust and Actix-Web. My task now is to send a request (ping-request) from this server to another server every 10 seconds. The ping-request itself is implemented in a async function:

async fn ping(client: web::Data<Client>, state: Data<AppState>) -> Result<HttpResponse, Error> {}

This is my simple server-main-function:

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    ::std::env::set_var("RUST_LOG", "debug");
    env_logger::init();
    let args = config::CliOptions::from_args();
    let config =
        config::Config::new(args.config_file.as_path()).expect("Failed to config");
    let address = config.address.clone();
    let app_state = AppState::new(config).unwrap();

    println!("Started http server: http://{}", address);

    HttpServer::new(move || {
        App::new()
            .data(app_state.clone())
            .app_data(app_state.clone())
            .data(Client::default())
            .default_service(web::resource("/").route(web::get().to(index)))
    })
    .bind(address)?
    .run()
    .await
}

I tried using tokio, but this was just to complicated because all the different async function and their lifetimes.

So is there any easy way within actix-web to execute this ping-function (maybe as a service) every 10 seconds after the server started?

Thanks!

Samuel Dressel
  • 1,181
  • 2
  • 13
  • 27
  • 1
    Use [`actix::spawn`](https://docs.rs/actix/0.10.0/actix/fn.spawn.html) to start a task that uses [`tokio::time::delay_for`](https://docs.rs/tokio/0.2.22/tokio/time/fn.delay_for.html) in a loop to wait for 10s and execute the ping? – Jmb Sep 23 '20 at 11:49
  • 2
    There's also a [`run_interval`](https://docs.rs/actix/0.10.0/actix/prelude/trait.AsyncContext.html#method.run_interval) which "Spawns a job to execute the given closure periodically, at a specified fixed interval." – Masklinn Sep 23 '20 at 12:49

2 Answers2

14

See actix_rt::spawn and actix_rt::time::interval.

Here is an example:

spawn(async move {
    let mut interval = time::interval(Duration::from_secs(10));
    loop {
        interval.tick().await;
        // do something
    }
});
QuarticCat
  • 1,314
  • 6
  • 20
0
#[get("/run_c")]
async fn run_c() -> impl Responder {
    //tokio::time::delay_until(Duration::from_secs(5)).await;
    //time::interval(period)
    let mut interval = time::interval(Duration::from_millis(10));
    loop {
        interval.tick().await;
        print!("hello");
        HttpResponse::Ok().body("Hello world!");
    }

}

This works but only thing being it wont reurn http resposnse to caller

Raj Patil
  • 1
  • 1