[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(""). 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(|| {
                // enable logger
                .service(web::resource("/index.html").to(|| async { "Hello world!" }))

    /// 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();

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



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