Files
Sébastien Stormacq d456396581 Add support for Lambda Managed Instances without changing the public API [CORE] (#629)
AWS launched [Lambda Managed
Instances](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html),
i.e Lambda functions running on EC2 instances.

This comes with [a major change in the programming
model](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html#lambda-managed-instances-concurrency-model)
as function handlers are now allowed to run concurrently on the same
machine (multiple in flight events being processed in parallel in the
same execution environment). The maximum concurrency per runtime
environment is controlled by the user.

This PR adds support for running multiple Runtime Interface Clients
(RICs) concurrently when deployed on Lambda Managed Instances, enabling
the runtime to handle multiple invocations simultaneously within a
single execution environment.

This PR is a followup to
https://github.com/awslabs/swift-aws-lambda-runtime/pull/617 which used
another approach to support Lambda Managed Instances by changing the
public API and requiring that all handlers must conform to `Sendable`.
The original PR was closed as we agreed that only a fraction of the
Lambda functions will be deployed on EC2 and it was not worth adding a
`Sendable` requirement for all.

**Changes**

- **Introduced thread-safe LambdaManagedRuntime**: Created new
Sendable-conforming runtime class that supports concurrent handler
execution with atomic guards to prevent multiple runtime instances and
thread-safe handler requirements (`Handler: StreamingLambdaHandler &
Sendable`)

- **Implemented ServiceLifecycle integration**: Added managed runtime
support for structured concurrency lifecycle management, allowing proper
startup/shutdown coordination in multi-concurrent environments

This PR contains only changes to the core runtime, convenience
functions, handlers, adapters, and a comprehensive example will be added
in a follow up PR.

**Context**
Lambda Managed Instances support multi-concurrent invocations where
multiple invocations execute simultaneously within the same execution
environment. The runtime now detects the configured concurrency level
and launches the appropriate number of RICs to handle concurrent
requests efficiently.

When `AWS_LAMBDA_MAX_CONCURRENCY` is 1 or unset, the runtime maintains
the existing single-threaded behaviour for optimal performance on
traditional Lambda deployments.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sebastien Stormacq <stormacq@amazon.lu>
2026-02-12 00:17:04 +01:00

80 lines
3.1 KiB
Swift

// swift-tools-version:6.0
import PackageDescription
let defaultSwiftSettings: [SwiftSetting] = [
.define("FoundationJSONSupport"),
.define("ServiceLifecycleSupport"),
.define("LocalServerSupport"),
.define("ManagedRuntimeSupport"),
.enableExperimentalFeature(
"AvailabilityMacro=LambdaSwift 2.0:macOS 15.0"
),
]
let package = Package(
name: "swift-aws-lambda-runtime",
products: [
.library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]),
// plugin to package the lambda, creating an archive that can be uploaded to AWS
// requires Linux or at least macOS v15
.plugin(name: "AWSLambdaPackager", targets: ["AWSLambdaPackager"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.92.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.8.0"),
.package(url: "https://github.com/apple/swift-collections.git", from: "1.3.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.9.0"),
],
targets: [
.target(
name: "AWSLambdaRuntime",
dependencies: [
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "Logging", package: "swift-log"),
.product(name: "NIOHTTP1", package: "swift-nio"),
.product(name: "NIOPosix", package: "swift-nio"),
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
],
swiftSettings: defaultSwiftSettings
),
.plugin(
name: "AWSLambdaPackager",
capability: .command(
intent: .custom(
verb: "archive",
description:
"Archive the Lambda binary and prepare it for uploading to AWS. Requires docker on macOS or non Amazonlinux 2 distributions."
),
permissions: [
.allowNetworkConnections(
scope: .docker,
reason: "This plugin uses Docker to create the AWS Lambda ZIP package."
)
]
)
),
.testTarget(
name: "AWSLambdaRuntimeTests",
dependencies: [
.byName(name: "AWSLambdaRuntime"),
.product(name: "NIOTestUtils", package: "swift-nio"),
.product(name: "NIOFoundationCompat", package: "swift-nio"),
],
swiftSettings: defaultSwiftSettings
),
// for perf testing
.executableTarget(
name: "MockServer",
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "NIOHTTP1", package: "swift-nio"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOPosix", package: "swift-nio"),
],
swiftSettings: defaultSwiftSettings
),
]
)