简体   繁体   中英

How to have a connection with lazy static to S3 from Rust?

I am trying to replicate one of our Python lambda function to Rust and got stuck at the beginning with having a client to S3.

In Python it is simple, during the Lambda initialisation I declare a variable. However, when using Rust it is a bit more complicated.

As a newcomer to Rust dealing with async in a lazy_static setup is difficult.

use aws_config::meta::region::RegionProviderChain;
use aws_config::SdkConfig;
use aws_sdk_s3::Client as S3Client;
use lambda_http::Error as LambdaHttpError;
use lambda_http::{run, service_fn, Body, Error, Request, Response};
use lazy_static::lazy_static;

async fn connect_to_s3() -> S3Client {
    let region_provider: RegionProviderChain =
        RegionProviderChain::default_provider().or_else("eu-west-1");
    let config = aws_config::load_from_env().await;
    let client: S3Client = S3Client::new(&config);

    client
}

lazy_static! {
    static ref S3_CLIENT: S3Client = connect_to_s3();
}

This throws the following error:

error[E0308]: mismatched types
  --> src/bin/lambda/rora.rs:20:38
   |
20 |     static ref S3_CLIENT: S3Client = connect_to_s3();
   |                           --------   ^^^^^^^^^^^^^^^ expected struct `aws_sdk_s3::Client`, found opaque type
   |                           |
   |                           expected `aws_sdk_s3::Client` because of return type
   |
note: while checking the return type of the `async fn`
  --> src/bin/lambda/rora.rs:10:29
   |
10 | async fn connect_to_s3() -> S3Client {
   |                             ^^^^^^^^ checked the `Output` of this `async fn`, found opaque type
   = note:   expected struct `aws_sdk_s3::Client`
           found opaque type `impl Future<Output = aws_sdk_s3::Client>`
help: consider `await`ing on the `Future`
   |
20 |     static ref S3_CLIENT: S3Client = connect_to_s3().await;
   |                                                     ++++++

How can I initialize the connection to s3 during setup of the lambda?

After reviewing a bunch of code on github and talking to some of the Rust devs I know here is the current best option that I am aware of:

use async_once::AsyncOnce;
use lazy_static::lazy_static;
use aws_config::meta::region::RegionProviderChain;
use aws_sdk_glue::Client as GlueClient;
use aws_sdk_s3::Client as S3Client;

lazy_static! {
    static ref S3_CLIENT: AsyncOnce<S3Client> = AsyncOnce::new(async {
        let region_provider = RegionProviderChain::default_provider().or_else("eu-west-1");
        let config = aws_config::from_env().region(region_provider).load().await;

        S3Client::new(&config)
    });
    static ref GLUE_CLIENT: AsyncOnce<GlueClient> = AsyncOnce::new(async {
        let region_provider = RegionProviderChain::default_provider().or_else("eu-west-1");
        let config = aws_config::from_env().region(region_provider).load().await;

        GlueClient::new(&config)
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM