Hello,
I am trying to refactor some working code, replacing a struct with a trait so that I can facilitate my life during unit tests.
This operation causes the compiler to complain about the lifetime.
error[E0759]: `app_client` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
|
47 | pub async fn execute(app_client: &dyn WriterAppInitialisation, event: LambdaEvent<SqsEvent>) -> Result<Value, Error> {
| ^^^^^^^^^^ ---------------------------- this data with an anonymous lifetime `'_`...
| |
| ...is used here...
...
52 | let shared_client = Arc::from(app_client.clone());
| ---------- ...is used here...
...
59 | tasks.push(tokio::spawn(async move {
| ------------ ...and is required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by this bound
-->.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/task/spawn.rs:127:28
|
127 | T: Future + Send + 'static,
I am reading all around, but I do not get why.
#[derive(Debug, Clone, Builder)]
pub struct WriterAppClient {
#[builder(setter(into))]
pub dynamo_db_client: aws_sdk_dynamodb::Client,
#[builder(setter(into))]
pub add_query: AddQuery,
}
#[cfg_attr(test, automock)]
#[async_trait]
pub trait WriterAppInitialisation: Send + Sync {
async fn add_query(&self, item: &MyStruct) -> Result<(), ApplicationError>;
}
#[async_trait]
impl WriterAppInitialisation for WriterAppClient {
async fn add_query(&self, item: &MyStruct) -> Result<(), ApplicationError> {
self.add_query.execute(item).await
}
}
#[tokio::main]
async fn main() -> Result<(), Error> {
// stuff
let app_client = WriterAppClient::builder()
.add_query(query)
.dynamo_db_client(dynamodb_client.clone())
.build();
lambda_runtime::run(service_fn(|event: LambdaEvent<SqsEvent>| {
execute(&app_client, event)
}))
.await?;
Ok(())
}
//It is all working with the struct WriterAppClient
//pub async fn execute(app_client: &WriterAppClient, event: LambdaEvent<SqsEvent>) -> Result<Value, Error> {
pub async fn execute(app_client: &dyn WriterAppInitialisation, event: LambdaEvent<SqsEvent>) -> Result<Value, Error> {
let mut tasks = Vec::with_capacity(event.payload.records.len());
let shared_client = Arc::new(app_client.clone());
for record in event.payload.records.into_iter() {
let shared_client = shared_client.clone();
tasks.push(tokio::spawn(async move {
if let Some(body) = &record.body {
let request = serde_json::from_str::<MyStruct>(&body);
if let Ok(request) = request {
shared_client.add_query(&request)
.await
.map_or_else(|e| {
println!("ERROR {:?}", e);
}, |_| ());
}
}
}));
}
join_all(tasks).await;
//other stuff
}
I am not really sure why and how to move forward.
Is anyone kind enough to explain what is wrong and why?