lamedh-dev / aws-lambda-rust-runtime

Apache License 2.0
84 stars 13 forks source link

Support for persistent state #17

Closed jessbowers closed 3 years ago

jessbowers commented 3 years ago

I'm having trouble integrating with an older project due to the Handler requirement to be an async function & my need to persist state between handler calls.

In my old code, I was using a sync handler & calling block_on to wait for my future to complete:

   let app_state = AppState::new(&context);

    lambda!(
        |request: lambda_http::Request, _context| -> Result<(), HandlerError> {
            ...
            let datastore = app_state.datastore.clone();
            let fut = handle_request(data.version, datastore);
            system.block_on(fut.map_err(Into::into))
        }
    );

With v0.3.0 I've tried using a closure, no go because async closures can't have arguments, and they are FnOnce. I've also tried a Pin<Box> return type but I'm getting errors due to Futures not being Sync.

It seems like the solution is to either implement a sync Handler or a method for sharing state between handler calls. Or just give up & instantiate all state with each handler call. How are others doing this?

jessbowers commented 3 years ago

Ok I think I've figured this out with a solution like this:


struct MyLambdaHandler {
    pub state: AppState,
}

impl Handler for MyLambdaHandler {
    type Response = String;
    type Error = MyLambdaError;
    type Fut = Pin<Box<dyn Future<Output = Result<String, MyLambdaError>> + Send + 'static>>;

    fn call(&mut self, _event: Request, _context: Context) -> Self::Fut {
        let datastore = self.state.datastore.clone();
        let fut = handle_request(datastore);
        Box::pin(fut)
    }
}

#[tokio::main]
async fn main() -> Result<(), HandlerError> {

    ....
    let app_state = AppState::new(&context);
    lambda::run(handler(MyLambdaHandler { state: app_state })).await?;
    Ok(())
}
calavera commented 3 years ago

Thanks for opening this issue @jessbowers! I was wondering you wouldn't mind adding that code to the examples, that way other people can benefit from it. I'll leave this issue open for now, but I'll close it in a couple of days to give you time to decide (it's ok if you don't want to add it).

jessbowers commented 3 years ago

Opened PR#18 with example