Skip to content

feat(rust): add second example using non-op internal extension, expand README #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions rust-demo/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
# rust graceful shutdown demo

This folder contains a simple rust function with [CloudWatch Lambda Insight](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-insights.html) enabled. CloudWatch Lambda Insight is
## Generating graceful shutdown signals

In order for Lambda to support graceful shutdown, at least one extension must be registered for your function.
This folder contains two examples demonstrating this. One uses an external extension, and one uses Rust `lambda-runtime` crate's
[`spawn_graceful_shutdown_handler() helper`] function,
which is backed by an internal extension.

For more information on the difference between the two, see [these Lambda Extensions API docs](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).

### Internal extension

The simplest way to enable shutdown signals in a `Rust` lambda is via [`spawn_graceful_shutdown_handler() helper`] function in the `lambda-runtime`. Under the hood, this registers an internal extension from wtihin your handler process.

The registered extension is a dummy no-op extension that doesn't subscribe to any events. This is very lightweight since it spawns a `tokio` task that keeps open a long-running connection with the Lambda execution environment, that never receives data. It therefore is essentially never woken and just occupies a small amount of heap memory.

The helper also accepts a callback that includes the logic to fire on `SIGTERM` or `SIGINT`, and generates the boilerplate to react to those signals for us.

You can also manually implement your own internal extension registration, if you want an internal extension that has
useful functionality. For instance, see this example of an internal extension that flushes telemetry: [ref](https://github.com/awslabs/aws-lambda-rust-runtime/blob/main/examples/extension-internal-flush). In that case, you could still use the helper, or you could also directly spawn signal handlers as demonstrated in the [Signal handling in the function](#signal-handling-in-the-function).

### External extension

Alternately, you can receive shutdown signals if an external extension is registered with the runtime. An external extension runs as a separate process alongside your function's process. This does not require code changes in your function handler (besides signal handling logic), but it might add additional overhead if you don't actually need an external extension.

The external extension example assumes that the [CloudWatch Lambda Insight](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-insights.html) is enabled. CloudWatch Lambda Insight is a
monitoring and troubleshooting solution for serverless application. Its agent is an external extension. Any external
extension will work. We use Lambda Insight extension simply because it is readily available.
extension will work. We use Lambda Insight extension simply because it is readily available and useful. Note that this may incurs additional billing fees.

*It is recommended to use the latest [Lambda Insights extension](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html)*
```yaml
Expand All @@ -14,8 +38,10 @@ extension will work. We use Lambda Insight extension simply because it is readil
- CloudWatchLambdaInsightsExecutionRolePolicy
```

In the function, a simple signal handler is added. It will be executed when the lambda runtime receives
a `SIGTERM`、`SIGINT` signal. You can also add more signal types yourself.
## Signal handling in the function

Inside our external extension example, or inside the [`spawn_graceful_shutdown_handler() helper`], a simple signal handler is added. It will be executed when the lambda runtime receives a `SIGTERM`、`SIGINT` signal. You can customize the logic that will fire when one of the signals is received.


```rust
// Handle SIGTERM signal:
Expand All @@ -28,19 +54,24 @@ tokio::spawn(async move {
_sigint = sigint.recv() => {
println!("[runtime] SIGINT received");
println!("[runtime] Graceful shutdown in progress ...");
// additional logic
println!("[runtime] Graceful shutdown completed");
std::process::exit(0);
},
_sigterm = sigterm.recv()=> {
println!("[runtime] SIGTERM received");
println!("[runtime] Graceful shutdown in progress ...");
// additional logic
println!("[runtime] Graceful shutdown completed");
std::process::exit(0);
},
}
});
```
Use the following AWS SAM CLI commands to build and deploy this demo.

## Deploy and Test

Use the following AWS SAM CLI commands from within one of the two examples' subdirectories to build and deploy this demo.

```bash
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-rust.html#building-rust-prerequisites
Expand All @@ -54,7 +85,7 @@ Take note of the output value of `RustHelloWorldApi`. Use curl to invoke the api
curl "replace this with value of RustHelloWorldApi"
```

Waite for several minutes, check the function's log messages in CloudWatch. If you see a log line containing "SIGTERM
Wait for several minutes, check the function's log messages in CloudWatch. If you see a log line containing "SIGTERM
received", it works!

for example:
Expand Down Expand Up @@ -92,4 +123,7 @@ is an experimental package. It is subject to change and intended only for evalua
- [Building Lambda functions with Rust](https://docs.aws.amazon.com/lambda/latest/dg/lambda-rust.html)
- [AWS SAM Documentation](https://docs.aws.amazon.com/serverless-application-model/)
- [Building Rust Lambda functions with Cargo Lambda](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-rust.html)
- [cargo-lambda](https://www.cargo-lambda.info/)
- [cargo-lambda](https://www.cargo-lambda.info/)


[`spawn_graceful_shutdown_handler() helper`]: https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html
16 changes: 0 additions & 16 deletions rust-demo/rust_app/Cargo.toml

This file was deleted.

Loading