23 个版本

0.6.13 2023 年 1 月 8 日
0.6.12 2022 年 10 月 30 日
0.6.11 2022 年 9 月 25 日
0.6.8 2022 年 7 月 24 日
0.3.2 2021 年 11 月 6 日

网络编程 中排名第 530

MIT/Apache

52KB
783

lambda-runtime-types

此 crate 提供了用于简化 Rust 中 lambda 函数创建的类型和特性。它提供了事件和返回类型以及针对各种 lambda 类型的特定运行器。

无共享数据的简单 Lambda

创建一个普通的 lambda 非常简单。首先创建一个实现了 Runner 的类型,然后将其用于 execexec_tokio 函数

struct Runner;

#[async_trait::async_trait]
impl<'a> lambda_runtime_types::Runner<'a, (), (), ()> for Runner {
    async fn run(shared: &'a (), event: lambda_runtime_types::LambdaEvent<'a, ()>) -> anyhow::Result<()> {
        // Run code on every invocation
        Ok(())
    }

    async fn setup(_region: &'a str) -> anyhow::Result<()> {
        // Setup logging to make sure that errors are printed
        Ok(())
    }
}

pub fn main() -> anyhow::Result<()> {
    lambda_runtime_types::exec_tokio::<_, _, Runner, _>()
}

可用的 lambda 类型

有各种模块预定义了事件和返回类型,以及针对不同 lambda 用法的专用运行器特性。查看模块以获取示例或用法。

自定义事件和返回类型

如果预定义的类型不够用,可以使用自定义类型,只要事件类型实现了 serde::Deserialize 并且返回类型实现了 serde::Serialize

#[derive(serde::Deserialize, Debug)]
struct Event {
    #[serde(flatten)]
    attributes: std::collections::HashMap<String, serde_json::Value>,
}

#[derive(serde::Serialize, Debug)]
struct Return {
    data: std::borrow::Cow<'static, str>,
}

struct Runner;

#[async_trait::async_trait]
impl<'a> lambda_runtime_types::Runner<'a, (), Event, Return> for Runner {
    async fn run(shared: &'a (), event: lambda_runtime_types::LambdaEvent<'a, Event>) -> anyhow::Result<Return> {
        println!("{:?}", event);
        Ok(Return {
            data: event
                .event
                .attributes
                .get("test")
                .and_then(|a| a.as_str())
                .map(ToOwned::to_owned)
                .map(Into::into)
                .unwrap_or_else(|| "none".into()),
        })
    }

    async fn setup(_region: &'a str) -> anyhow::Result<()> {
        // Setup logging to make sure that errors are printed
        Ok(())
    }
}

pub fn main() -> anyhow::Result<()> {
    lambda_runtime_types::exec_tokio::<_, _, Runner, _>()
}

共享数据

使用 AWS Lambda,可以在调用之间共享数据,只要两个调用使用相同的运行时环境。要使用此功能,可以定义一个共享数据类型,该类型将使用内部可变性来持久化数据。

#[derive(Default)]
struct Shared  {
    invocations: tokio::sync::Mutex<u64>,
}

struct Runner;

#[async_trait::async_trait]
impl<'a> lambda_runtime_types::Runner<'a, Shared, (), ()> for Runner {
    async fn run(shared: &'a Shared, event: lambda_runtime_types::LambdaEvent<'a, ()>) -> anyhow::Result<()> {
        let mut invocations = shared.invocations.lock().await;
        *invocations += 1;
        Ok(())
    }

    async fn setup(_region: &'a str) -> anyhow::Result<Shared> {
        // Setup logging to make sure that errors are printed
        Ok(Shared::default())
    }
}

pub fn main() -> anyhow::Result<()> {
    lambda_runtime_types::exec_tokio::<_, _, Runner, _>()
}

重要的是要知道,lambda 执行环境永远不会同时运行多个调用。因此,可以将互斥锁在整个调用期间保持解锁状态,因为它永远不会阻塞其他调用。实际上,甚至建议这样做,以确保没有不必要的操作会减慢 lambda 执行时间。

超时处理

此软件包实现了超时处理逻辑。通常情况下,如果一个lambda函数遇到超时,它不会创建错误,而错误也不会通过on_error目的地传播。

为了解决这个问题,设置了一个超时处理器,它将在lambda函数即将超时前100毫秒“失败”,创建一个错误并传播。然而,无法保证这个处理器能够在时间上失败。它只有在有多个tokio线程或主lambda代码正在等待的情况下才会工作,这样tokio就有机会切换任务(或并行运行它们)并使执行失败。

内存耗尽

在运行lambda函数时,还需要考虑内存耗尽的问题。不幸的是,在Rust中无法检查当前的内存使用情况。因此,也无法在遇到OOF之前失败。在运行lambda函数时,可能需要设置检查来验证lambda函数是否成功完成,并且没有遇到OOF,因为这些错误也不会传播到on_error目的地。

许可:MIT OR Apache-2.0

依赖关系

~6–24MB
~309K SLoC