0

I've been struggling with this for a while now and just going in circles, so I'm hoping someone can point out where I'm going wrong.

I'm playing with Actix Web, and setting up my first handlers - which is a simple Healthcheck of the system. So what I've got is:

  • A Healthcheck trait defining a healthcheck
  • A HealthcheckHandler struct that implements the Handler trait (This is an Actix Web concept) and contains a HashMap
  • A function that builds an App instance for the healthcheck routes (This is an Actix Web concept) by taking a HashMap<String, &Healthcheck>

When I try to build this I get errors that the trait "cannot be sent between threads safely".

I've tried with &Healthcheck, Box<Healthcheck>, Box<Healthcheck + Send> based on another answer on here, and even Mutex<&Healthcheck> all without luck, but all with subtly different errors. It all seems to be around needing to implement some combinations of Sync, Send and/or Clone, but I'm not sure how to get around that here.

Any pointers to what I should to fix this?

Actual example code:

pub trait Healthcheck {
    fn check(&self) -> Result<String, String>;
}
struct HealthcheckHandler {
    handlers: HashMap<String, Box<Healthcheck>>,
}
pub fn build_app(handlers: HashMap<String, Box<Healthcheck>>) -> App<()> {
    let handler = HealthcheckHandler {
        handlers: handlers,
    };

    App::new()
        .prefix("/health")
        .resource("", |r| {
            r.get().h(handler);
        })
}
pub fn start(settings: HashMap<String, String>) {
    let mut healthchecks: HashMap<String, Box<Healthcheck>> = HashMap::new();

    let server = server::new(|| { // <-- This is where the errors happen. This closure is used to spawn threads.
        vec![
            build_app(healthchecks).middleware(middleware::Logger::default())
        ]
    });
}

Cheers

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Graham
  • 4,095
  • 4
  • 29
  • 37
  • Please review how to create a [MCVE] and then [edit] your question to include it. We cannot tell what crates (and their versions), types, traits, fields, etc. are present in the code. Try to reproduce your error in a brand new Cargo project. There are [Rust-specific MCVE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. – Shepmaster Apr 16 '19 at 17:08
  • For example, `r.get().h(handler)` appears to be invalid for other reasons. – Shepmaster Apr 16 '19 at 17:09
  • TL;DR the duplicates: `pub trait Healthcheck: Send + Sync` and `let mut handlers = HashMap::new(); let handler = Arc::new(HealthcheckHandler { handlers });` ` – Shepmaster Apr 16 '19 at 17:15
  • 1
    In modern Rust, it's encouraged to use `dyn Trait` to clearly indicate that you are deliberately using a trait object. Here, it would be `Box`. – Shepmaster Apr 16 '19 at 17:19

0 Answers0