From 82539a9532627aca7101e88689160361ac2cc346 Mon Sep 17 00:00:00 2001 From: jlizen Date: Mon, 12 May 2025 16:53:22 +0000 Subject: [PATCH 1/2] fix(lambda-runtime,lambda-integration-tests): make spawn_graceful_shutdown_handler() async, await the extension being registered before spawning background extension handler task --- lambda-integration-tests/src/helloworld.rs | 2 +- lambda-runtime/src/lib.rs | 42 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lambda-integration-tests/src/helloworld.rs b/lambda-integration-tests/src/helloworld.rs index 92fc7d80..b40cd0c6 100644 --- a/lambda-integration-tests/src/helloworld.rs +++ b/lambda-integration-tests/src/helloworld.rs @@ -8,7 +8,7 @@ use lambda_runtime::{service_fn, tracing, Error, LambdaEvent}; async fn main() -> Result<(), Error> { tracing::init_default_subscriber(); let func = service_fn(func); - lambda_runtime::spawn_graceful_shutdown_handler(|| async move {}); + lambda_runtime::spawn_graceful_shutdown_handler(|| async move {}).await; lambda_runtime::run(func).await?; Ok(()) } diff --git a/lambda-runtime/src/lib.rs b/lambda-runtime/src/lib.rs index e1b15a25..5598d104 100644 --- a/lambda-runtime/src/lib.rs +++ b/lambda-runtime/src/lib.rs @@ -131,7 +131,7 @@ where /// /// You can use this future to execute cleanup or flush related logic prior to runtime shutdown. /// -/// This function must be called prior to [lambda_runtime::run()]. +/// This function's returned future must be resolved prior to [lambda_runtime::run()]. /// /// Note that this implicitly also registers and drives a no-op internal extension that subscribes to no events. /// This extension will be named `_lambda-rust-runtime-no-op-graceful-shutdown-helper`. This extension name @@ -166,7 +166,7 @@ where /// let shutdown_hook = || async move { /// std::mem::drop(log_guard); /// }; -/// lambda_runtime::spawn_graceful_shutdown_handler(shutdown_hook); +/// lambda_runtime::spawn_graceful_shutdown_handler(shutdown_hook).await; /// /// lambda_runtime::run(func).await?; /// Ok(()) @@ -178,29 +178,29 @@ where /// ``` #[cfg(all(unix, feature = "graceful-shutdown"))] #[cfg_attr(docsrs, doc(cfg(all(unix, feature = "tokio-rt"))))] -pub fn spawn_graceful_shutdown_handler(shutdown_hook: impl FnOnce() -> Fut + Send + 'static) +pub async fn spawn_graceful_shutdown_handler(shutdown_hook: impl FnOnce() -> Fut + Send + 'static) where Fut: Future + Send + 'static, { - tokio::task::spawn(async move { - // You need an extension registered with the Lambda orchestrator in order for your process - // to receive a SIGTERM for graceful shutdown. - // - // We accomplish this here by registering a no-op internal extension, which does not subscribe to any events. - // - // This extension is cheap to run since after it connects to the lambda orchestration, the connection - // will just wait forever for data to come, which never comes, so it won't cause wakes. - let extension = lambda_extension::Extension::new() - // Don't subscribe to any event types - .with_events(&[]) - // Internal extension names MUST be unique within a given Lambda function. - .with_extension_name("_lambda-rust-runtime-no-op-graceful-shutdown-helper") - // Extensions MUST be registered before calling lambda_runtime::run(), which ends the Init - // phase and begins the Invoke phase. - .register() - .await - .expect("could not register no-op extension for graceful shutdown"); + // You need an extension registered with the Lambda orchestrator in order for your process + // to receive a SIGTERM for graceful shutdown. + // + // We accomplish this here by registering a no-op internal extension, which does not subscribe to any events. + // + // This extension is cheap to run since after it connects to the lambda orchestration, the connection + // will just wait forever for data to come, which never comes, so it won't cause wakes. + let extension = lambda_extension::Extension::new() + // Don't subscribe to any event types + .with_events(&[]) + // Internal extension names MUST be unique within a given Lambda function. + .with_extension_name("_lambda-rust-runtime-no-op-graceful-shutdown-helper") + // Extensions MUST be registered before calling lambda_runtime::run(), which ends the Init + // phase and begins the Invoke phase. + .register() + .await + .expect("could not register no-op extension for graceful shutdown"); + tokio::task::spawn(async move { let graceful_shutdown_future = async move { let mut sigint = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt()).unwrap(); let mut sigterm = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).unwrap(); From dc0670f92c8c2421a5ed9d9b16132bf40305b3b9 Mon Sep 17 00:00:00 2001 From: jlizen Date: Thu, 15 May 2025 20:30:30 +0000 Subject: [PATCH 2/2] fix(ci/cd): pin back idna_adapter to avoid breaking msrv checks due to test dependencies --- lambda-runtime/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lambda-runtime/Cargo.toml b/lambda-runtime/Cargo.toml index 68aa713a..4c4cab2a 100644 --- a/lambda-runtime/Cargo.toml +++ b/lambda-runtime/Cargo.toml @@ -73,6 +73,9 @@ hyper-util = { workspace = true, features = [ "server-auto", "tokio", ] } +# pin back to pre-1.2.1 to avoid breaking rust MSRV of 1.81: +# https://github.com/hsivonen/idna_adapter/commit/f948802e3a2ae936eec51886eefbd7d536a28791 +idna_adapter = "=1.2.0" # Self dependency to enable the graceful-shutdown feature for tests lambda_runtime = { path = ".", features = ["tracing", "graceful-shutdown"] } pin-project-lite = { workspace = true }