lambda_runtime_context 0.1.0

Task-local runtime deadline helpers for async Rust workers and AWS Lambda handlers.
Documentation
  • Coverage
  • 100%
    6 out of 6 items documented1 out of 6 items with examples
  • Size
  • Source code size: 14.49 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.33 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 51s Average build duration of successful builds.
  • all releases: 51s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • quietscroll/lambda-runtime-context
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • ernestas-poskus

lambda_runtime_context

Cargo Test docs.rs

Task-local runtime deadline helpers for async Rust workers.

lambda_runtime_context stores an invocation deadline in a Tokio task-local and exposes small helpers for deciding whether enough execution time remains to start more work. It is designed for AWS Lambda handlers, queue consumers, and other bounded async runtimes where a worker should stop early and re-enqueue remaining work before the platform terminates the process.

Install

[dependencies]
lambda_runtime_context = "0.1"

Core Idea

Wrap an async execution scope with a deadline timestamp in milliseconds since the Unix epoch:

lambda_runtime_context::scope_deadline(deadline_ms, async {
    // Work in this async scope can read the deadline.
})
.await;

Then check the remaining time before starting expensive or non-interruptible work:

use std::time::Duration;

if lambda_runtime_context::is_duration_available(Duration::from_secs(30)) {
    process_next_item().await;
} else {
    enqueue_remaining_work().await;
}
# async fn process_next_item() {}
# async fn enqueue_remaining_work() {}

AWS Lambda Usage

AWS Lambda exposes an invocation deadline as milliseconds since the Unix epoch. Pass that value into scope_deadline at the handler boundary:

use std::time::Duration;

async fn handle(deadline_ms: u64) {
    lambda_runtime_context::scope_deadline(deadline_ms, async {
        while lambda_runtime_context::is_duration_available(Duration::from_secs(30)) {
            process_next_message().await;
        }

        reenqueue_remaining_messages().await;
    })
    .await;
}

async fn process_next_message() {}
async fn reenqueue_remaining_messages() {}

time_remaining() returns None when no deadline has been scoped. This keeps local development and tests explicit: code can choose whether missing context means "do not start bounded work" or should be handled by a local fallback.

Spawned Tasks

Tokio task-locals are scoped to the current task. A task created with tokio::spawn does not automatically inherit the deadline. Capture the current deadline and scope it again inside the spawned task:

async fn spawn_work() {
    if let Some(deadline_ms) = lambda_runtime_context::current_deadline_ms() {
        tokio::spawn(async move {
            lambda_runtime_context::scope_deadline(deadline_ms, async {
                do_work().await;
            })
            .await;
        });
    }
}

async fn do_work() {}

API

Publishing

Before publishing:

cargo test -p lambda_runtime_context
cargo package -p lambda_runtime_context

Then publish from the workspace root:

cargo publish -p lambda_runtime_context

The crate is self-contained and only depends on tokio and time.