[Actix] Is there a better way of keeping a persistent state than lazy_static?

It would really be nice to just create an instance, serv, of the server below, and thereafter, call serv.execute("127.0.0.1:8080"). Then, inside the execute closure's .service(web::resource("/").to(X)) , it would be nice to use self.stage0 instead of using Self::stage0 coupled with a lazy_static instance. Is there a better way about this than I am setting this up?

use actix_web::{middleware, web, App, HttpRequest, HttpServer};
use std::sync::atomic::{AtomicUsize, Ordering};
use lazy_static::*;

lazy_static! {
/// Server
    pub static ref SERVER: MyTaskQueueServer = MyTaskQueueServer::new();
}

/// A device for handling both actix requests, AND keeping track of those requests
pub struct MyTaskQueueServer {
    counter: AtomicUsize
}


impl MyTaskQueueServer {
    /// Creates a new instance of the task server
    pub fn new() -> Self {
        Self { counter: AtomicUsize::new(0) }
    }

    /// Begins the server
    pub async fn execute(addr: &str) -> std::io::Result<()> {
        HttpServer::new(|| {
            App::new()
                // enable logger
                .wrap(middleware::Logger::default())
                .service(web::resource("/index.html").to(|| async { "Hello world!" }))
                .service(web::resource("/").to(Self::stage0))
        })
            .bind(addr)?
            .run()
            .await
    }

    /// Gets and increments the counter atomically
    pub fn get_and_increment(&self) -> usize {
        self.counter.fetch_add(1, Ordering::SeqCst)
    }

    async fn stage0(req: HttpRequest) -> String {
        println!("REQ: {:?}", req);
        format!("Hello world {}!", SERVER.get_and_increment())
    }

}

Current code in main.rs:

async fn main() -> io::Result<()> {
    MyTaskQueueServer::execute().await // Not good, because I'm forced to use lazy_static
}

Desired setup:

async fn main() -> io::Result<()> {
    let server = MyTaskQueueServer::new();
    server.execute("127.0.0.1:8080").await
}

The preferred way of having shared state between requests in actix-web is via web::Data:

https://actix.rs/docs/application/#state
https://docs.rs/actix-web/2.0.0/actix_web/web/struct.Data.html

3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.