Lifetime in struct again


#1

I have a Iron webservice code where I define the struct as

struct Web<'a> {
   container : Arc<Mutex<&'a Container>>
 }

impl<'a> Handler for Web<'a> {
     fn handle(&self, _: &mut Request) -> IronResult<Response> {
            ....
            Ok(Response::with((content_type, status::Ok, INDEX)))
        }
 }

I would like to pass the to the struct the container parameter defined as

container : Arc<Mutex<&PipelineContainer>>

However, as usual, lifetimes are causing me problems

I get the error

The type `web::Web<'a>` does not fulfill the required lifetime

impl<'a> Handler for Web<'a> {
   |     ^^^^^^^

What am I doing wrong here ?

Thanks


#2

It looks like Handler requires that the implementer is also Sync and Send. The Web struct has a few issues in light of that:

  1. Mutex<&'a Container> is not going to be Sync. Since the Mutex simply holds a shared reference, it’s not protecting anything. Speaking of which, what is your intention behind putting a reference behind the Mutex, rather than the Mutex owning the value?
  2. I’m assuming Container is a trait. Have you declared that implementations must also be Send?
  3. Related to #1, Web<'a> is parametric over some arbitrary lifetime - that’s not going to make it Send or Sync since it may be holding references to its stack environment. In addition, Handler is also Any, and Any requires implementations to be 'static - no references at all or only 'static references.

#3

1, I am experimenting with the reference because my program runs code with this container and also sets up a webpage for control. I was trying to get around the problem of the container moving the container.
ie

crossbeam::scope(|scope| {
        scope.spawn(move || {
            web::serve(Arc::new(Mutex::new(container)).clone());
            container.run();  <- value used here after move
        });
    });

2, Is is a normal struct

Really container should last the lifetime of my program so can be static it that helps.


#4

An Arc<Mutex<Container>> should allow you to freely share the container across threads - just clone the Arc and pass that clone around (instead of references).

Really? Cause you’re showing a PipelineContainer elsewhere in your post, which makes me think Container is a trait.


#5

Sorry I renamed it when simplifying for the post and must have forgot to change it


#6

Gotcha. Ok, so then I’ll assume your container struct is Send and Sync, and we can ignore that part (but do indicate otherwise).

The core problems, then, are #1 and #3 from my post above. So I’d suggest you drop the lifetime from Web and just store an Arc<Mutex<Container>> in it. As mentioned, you can share the inner container by cloning the Arc and passing the cloned value to places that need shared ownership.