diff --git a/Sources/AWSLambdaRuntime/Context+Foundation.swift b/Sources/AWSLambdaRuntime/Context+Foundation.swift index f2fa9a75..a83237a7 100644 --- a/Sources/AWSLambdaRuntime/Context+Foundation.swift +++ b/Sources/AWSLambdaRuntime/Context+Foundation.swift @@ -16,7 +16,7 @@ import AWSLambdaRuntimeCore import struct Foundation.Date -extension NewLambdaContext { +extension LambdaContext { var deadlineDate: Date { let secondsSinceEpoch = Double(Int64(bitPattern: self.deadline.rawValue)) / -1_000_000_000 return Date(timeIntervalSince1970: secondsSinceEpoch) diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift index 1f59b8f7..6751afe9 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -66,13 +66,13 @@ extension LambdaCodableAdapter { } } -extension NewLambdaRuntime { - /// Initialize an instance with a ``NewLambdaHandler`` defined in the form of a closure **with a non-`Void` return type**. +extension LambdaRuntime { + /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a non-`Void` return type**. /// - Parameter body: The handler in the form of a closure. /// - Parameter encoder: The encoder object that will be used to encode the generic ``Output`` into a ``ByteBuffer``. ``JSONEncoder()`` used as default. /// - Parameter decoder: The decoder object that will be used to decode the incoming ``ByteBuffer`` event into the generic ``Event`` type. ``JSONDecoder()`` used as default. package convenience init( - body: @escaping (Event, NewLambdaContext) async throws -> Output, + body: @escaping (Event, LambdaContext) async throws -> Output, encoder: JSONEncoder = JSONEncoder(), decoder: JSONDecoder = JSONDecoder() ) @@ -94,11 +94,11 @@ extension NewLambdaRuntime { self.init(handler: handler) } - /// Initialize an instance with a ``NewLambdaHandler`` defined in the form of a closure **with a `Void` return type**. + /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a `Void` return type**. /// - Parameter body: The handler in the form of a closure. /// - Parameter decoder: The decoder object that will be used to decode the incoming ``ByteBuffer`` event into the generic ``Event`` type. ``JSONDecoder()`` used as default. package convenience init( - body: @escaping (Event, NewLambdaContext) async throws -> Void, + body: @escaping (Event, LambdaContext) async throws -> Void, decoder: JSONDecoder = JSONDecoder() ) where diff --git a/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift b/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift index 6748d526..29016b0e 100644 --- a/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift +++ b/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift @@ -36,19 +36,19 @@ package struct InvocationMetadata: Hashable { package let clientContext: String? package let cognitoIdentity: String? - package init(headers: HTTPHeaders) throws(NewLambdaRuntimeError) { + package init(headers: HTTPHeaders) throws(LambdaRuntimeError) { guard let requestID = headers.first(name: AmazonHeaders.requestID), !requestID.isEmpty else { - throw NewLambdaRuntimeError(code: .nextInvocationMissingHeaderRequestID) + throw LambdaRuntimeError(code: .nextInvocationMissingHeaderRequestID) } guard let deadline = headers.first(name: AmazonHeaders.deadline), let unixTimeInMilliseconds = Int64(deadline) else { - throw NewLambdaRuntimeError(code: .nextInvocationMissingHeaderDeadline) + throw LambdaRuntimeError(code: .nextInvocationMissingHeaderDeadline) } guard let invokedFunctionARN = headers.first(name: AmazonHeaders.invokedFunctionARN) else { - throw NewLambdaRuntimeError(code: .nextInvocationMissingHeaderInvokeFuctionARN) + throw LambdaRuntimeError(code: .nextInvocationMissingHeaderInvokeFuctionARN) } self.requestID = requestID diff --git a/Sources/AWSLambdaRuntimeCore/Lambda.swift b/Sources/AWSLambdaRuntimeCore/Lambda.swift index 267a14c3..86ee912b 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import Dispatch import Logging import NIOCore import NIOPosix @@ -28,7 +29,39 @@ import ucrt #error("Unsupported platform") #endif -enum Lambda {} +enum Lambda { + package static func runLoop( + runtimeClient: RuntimeClient, + handler: Handler, + logger: Logger + ) async throws where Handler: StreamingLambdaHandler { + var handler = handler + + while !Task.isCancelled { + let (invocation, writer) = try await runtimeClient.nextInvocation() + + do { + try await handler.handle( + invocation.event, + responseWriter: writer, + context: LambdaContext( + requestID: invocation.metadata.requestID, + traceID: invocation.metadata.traceID, + invokedFunctionARN: invocation.metadata.invokedFunctionARN, + deadline: DispatchWallTime(millisSinceEpoch: invocation.metadata.deadlineInMillisSinceEpoch), + logger: logger + ) + ) + } catch { + try await writer.reportError(error) + continue + } + } + } + + /// The default EventLoop the Lambda is scheduled on. + package static var defaultEventLoop: any EventLoop = NIOSingletons.posixEventLoopGroup.next() +} // MARK: - Public API diff --git a/Sources/AWSLambdaRuntimeCore/NewLambdaContext.swift b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift similarity index 97% rename from Sources/AWSLambdaRuntimeCore/NewLambdaContext.swift rename to Sources/AWSLambdaRuntimeCore/LambdaContext.swift index abd2e61f..a2236618 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambdaContext.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift @@ -20,7 +20,7 @@ import NIOCore /// Lambda runtime context. /// The Lambda runtime generates and passes the `LambdaContext` to the Lambda handler as an argument. -package struct NewLambdaContext: CustomDebugStringConvertible, Sendable { +package struct LambdaContext: CustomDebugStringConvertible, Sendable { final class _Storage: Sendable { let requestID: String let traceID: String @@ -127,8 +127,8 @@ package struct NewLambdaContext: CustomDebugStringConvertible, Sendable { invokedFunctionARN: String, timeout: DispatchTimeInterval, logger: Logger - ) -> NewLambdaContext { - NewLambdaContext( + ) -> LambdaContext { + LambdaContext( requestID: requestID, traceID: traceID, invokedFunctionARN: invokedFunctionARN, diff --git a/Sources/AWSLambdaRuntimeCore/NewLambdaHandlers.swift b/Sources/AWSLambdaRuntimeCore/LambdaHandlers.swift similarity index 84% rename from Sources/AWSLambdaRuntimeCore/NewLambdaHandlers.swift rename to Sources/AWSLambdaRuntimeCore/LambdaHandlers.swift index 2464a486..9637f0ea 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambdaHandlers.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaHandlers.swift @@ -26,7 +26,7 @@ package protocol StreamingLambdaHandler { /// - event: The invocation's input data. /// - responseWriter: A ``LambdaResponseStreamWriter`` to write the invocation's response to. /// If no response or error is written to `responseWriter` an error will be reported to the invoker. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. /// - Throws: /// How the thrown error will be handled by the runtime: /// - An invocation error will be reported if the error is thrown before the first call to @@ -39,7 +39,7 @@ package protocol StreamingLambdaHandler { mutating func handle( _ event: ByteBuffer, responseWriter: some LambdaResponseStreamWriter, - context: NewLambdaContext + context: LambdaContext ) async throws } @@ -64,7 +64,7 @@ package protocol LambdaResponseStreamWriter { /// /// - note: This handler protocol does not support response streaming because the output has to be encoded prior to it being sent, e.g. it is not possible to encode a partial/incomplete JSON string. /// This protocol also does not support the execution of background work after the response has been returned -- the ``LambdaWithBackgroundProcessingHandler`` protocol caters for such use-cases. -package protocol NewLambdaHandler { +package protocol LambdaHandler { /// Generic input type. /// The body of the request sent to Lambda will be decoded into this type for the handler to consume. associatedtype Event: Decodable @@ -75,12 +75,12 @@ package protocol NewLambdaHandler { /// Implement the business logic of the Lambda function here. /// - Parameters: /// - event: The generic ``Event`` object representing the invocation's input data. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. /// - Returns: A generic ``Output`` object representing the computed result. - func handle(_ event: Event, context: NewLambdaContext) async throws -> Output + func handle(_ event: Event, context: LambdaContext) async throws -> Output } -/// This protocol is exactly like ``NewLambdaHandler``, with the only difference being the added support for executing background +/// This protocol is exactly like ``LambdaHandler``, with the only difference being the added support for executing background /// work after the result has been sent to the AWS Lambda control plane. /// This is achieved by not having a return type in the `handle` function. The output is instead written into a /// ``LambdaResponseWriter``that is passed in as an argument, meaning that the ``handle(_:)`` function is then free to implement @@ -98,11 +98,11 @@ package protocol LambdaWithBackgroundProcessingHandler { /// - event: The generic ``Event`` object representing the invocation's input data. /// - outputWriter: The writer to send the computed response to. A call to `outputWriter.write(_:)` will return the response to the AWS Lambda response endpoint. /// Any background work can then be executed before returning. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. func handle( _ event: Event, outputWriter: some LambdaResponseWriter, - context: NewLambdaContext + context: LambdaContext ) async throws } @@ -121,67 +121,67 @@ package protocol LambdaResponseWriter { /// A ``StreamingLambdaHandler`` conforming handler object that can be constructed with a closure. /// Allows for a handler to be defined in a clean manner, leveraging Swift's trailing closure syntax. package struct StreamingClosureHandler: StreamingLambdaHandler { - let body: @Sendable (ByteBuffer, LambdaResponseStreamWriter, NewLambdaContext) async throws -> Void + let body: @Sendable (ByteBuffer, LambdaResponseStreamWriter, LambdaContext) async throws -> Void /// Initialize an instance from a handler function in the form of a closure. /// - Parameter body: The handler function written as a closure. package init( - body: @Sendable @escaping (ByteBuffer, LambdaResponseStreamWriter, NewLambdaContext) async throws -> Void + body: @Sendable @escaping (ByteBuffer, LambdaResponseStreamWriter, LambdaContext) async throws -> Void ) { self.body = body } - /// Calls the provided `self.body` closure with the ``ByteBuffer`` invocation event, the ``LambdaResponseStreamWriter``, and the ``NewLambdaContext`` + /// Calls the provided `self.body` closure with the ``ByteBuffer`` invocation event, the ``LambdaResponseStreamWriter``, and the ``LambdaContext`` /// - Parameters: /// - event: The invocation's input data. /// - responseWriter: A ``LambdaResponseStreamWriter`` to write the invocation's response to. /// If no response or error is written to `responseWriter` an error will be reported to the invoker. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. package func handle( _ request: ByteBuffer, responseWriter: some LambdaResponseStreamWriter, - context: NewLambdaContext + context: LambdaContext ) async throws { try await self.body(request, responseWriter, context) } } -/// A ``NewLambdaHandler`` conforming handler object that can be constructed with a closure. +/// A ``LambdaHandler`` conforming handler object that can be constructed with a closure. /// Allows for a handler to be defined in a clean manner, leveraging Swift's trailing closure syntax. -package struct ClosureHandler: NewLambdaHandler { - let body: (Event, NewLambdaContext) async throws -> Output +package struct ClosureHandler: LambdaHandler { + let body: (Event, LambdaContext) async throws -> Output /// Initialize with a closure handler over generic `Input` and `Output` types. /// - Parameter body: The handler function written as a closure. - package init(body: @escaping (Event, NewLambdaContext) async throws -> Output) where Output: Encodable { + package init(body: @escaping (Event, LambdaContext) async throws -> Output) where Output: Encodable { self.body = body } /// Initialize with a closure handler over a generic `Input` type, and a `Void` `Output`. /// - Parameter body: The handler function written as a closure. - package init(body: @escaping (Event, NewLambdaContext) async throws -> Void) where Output == Void { + package init(body: @escaping (Event, LambdaContext) async throws -> Void) where Output == Void { self.body = body } - /// Calls the provided `self.body` closure with the generic ``Event`` object representing the incoming event, and the ``NewLambdaContext`` + /// Calls the provided `self.body` closure with the generic ``Event`` object representing the incoming event, and the ``LambdaContext`` /// - Parameters: /// - event: The generic ``Event`` object representing the invocation's input data. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. - package func handle(_ event: Event, context: NewLambdaContext) async throws -> Output { + /// - context: The ``LambdaContext`` containing the invocation's metadata. + package func handle(_ event: Event, context: LambdaContext) async throws -> Output { try await self.body(event, context) } } -extension NewLambdaRuntime { +extension LambdaRuntime { /// Initialize an instance with a ``StreamingLambdaHandler`` in the form of a closure. /// - Parameter body: The handler in the form of a closure. package convenience init( - body: @Sendable @escaping (ByteBuffer, LambdaResponseStreamWriter, NewLambdaContext) async throws -> Void + body: @Sendable @escaping (ByteBuffer, LambdaResponseStreamWriter, LambdaContext) async throws -> Void ) where Handler == StreamingClosureHandler { self.init(handler: StreamingClosureHandler(body: body)) } - /// Initialize an instance with a ``NewLambdaHandler`` defined in the form of a closure **with a non-`Void` return type**, an encoder, and a decoder. + /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a non-`Void` return type**, an encoder, and a decoder. /// - Parameter body: The handler in the form of a closure. /// - Parameter encoder: The encoder object that will be used to encode the generic ``Output`` into a ``ByteBuffer``. /// - Parameter decoder: The decoder object that will be used to decode the incoming ``ByteBuffer`` event into the generic ``Event`` type. @@ -193,7 +193,7 @@ extension NewLambdaRuntime { >( encoder: Encoder, decoder: Decoder, - body: @escaping (Event, NewLambdaContext) async throws -> Output + body: @escaping (Event, LambdaContext) async throws -> Output ) where Handler == LambdaCodableAdapter< @@ -213,13 +213,13 @@ extension NewLambdaRuntime { self.init(handler: handler) } - /// Initialize an instance with a ``NewLambdaHandler`` defined in the form of a closure **with a `Void` return type**, an encoder, and a decoder. + /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a `Void` return type**, an encoder, and a decoder. /// - Parameter body: The handler in the form of a closure. /// - Parameter encoder: The encoder object that will be used to encode the generic ``Output`` into a ``ByteBuffer``. /// - Parameter decoder: The decoder object that will be used to decode the incoming ``ByteBuffer`` event into the generic ``Event`` type. package convenience init( decoder: Decoder, - body: @escaping (Event, NewLambdaContext) async throws -> Void + body: @escaping (Event, LambdaContext) async throws -> Void ) where Handler == LambdaCodableAdapter< diff --git a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntime.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntime.swift similarity index 83% rename from Sources/AWSLambdaRuntimeCore/NewLambdaRuntime.swift rename to Sources/AWSLambdaRuntimeCore/LambdaRuntime.swift index 41212b22..c01215ac 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntime.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntime.swift @@ -20,7 +20,7 @@ import NIOConcurrencyHelpers // We need `@unchecked` Sendable here, as `NIOLockedValueBox` does not understand `sending` today. // We don't want to use `NIOLockedValueBox` here anyway. We would love to use Mutex here, but this // sadly crashes the compiler today. -package final class NewLambdaRuntime: @unchecked Sendable where Handler: StreamingLambdaHandler { +package final class LambdaRuntime: @unchecked Sendable where Handler: StreamingLambdaHandler { // TODO: We want to change this to Mutex as soon as this doesn't crash the Swift compiler on Linux anymore let handlerMutex: NIOLockedValueBox> let logger: Logger @@ -38,12 +38,12 @@ package final class NewLambdaRuntime: @unchecked Sendable where Handler package func run() async throws { guard let runtimeEndpoint = Lambda.env("AWS_LAMBDA_RUNTIME_API") else { - throw NewLambdaRuntimeError(code: .missingLambdaRuntimeAPIEnvironmentVariable) + throw LambdaRuntimeError(code: .missingLambdaRuntimeAPIEnvironmentVariable) } let ipAndPort = runtimeEndpoint.split(separator: ":", maxSplits: 1) let ip = String(ipAndPort[0]) - guard let port = Int(ipAndPort[1]) else { throw NewLambdaRuntimeError(code: .invalidPort) } + guard let port = Int(ipAndPort[1]) else { throw LambdaRuntimeError(code: .invalidPort) } let handler = self.handlerMutex.withLockedValue { handler in let result = handler @@ -52,10 +52,10 @@ package final class NewLambdaRuntime: @unchecked Sendable where Handler } guard let handler else { - throw NewLambdaRuntimeError(code: .runtimeCanOnlyBeStartedOnce) + throw LambdaRuntimeError(code: .runtimeCanOnlyBeStartedOnce) } - try await NewLambdaRuntimeClient.withRuntimeClient( + try await LambdaRuntimeClient.withRuntimeClient( configuration: .init(ip: ip, port: port), eventLoop: self.eventLoop, logger: self.logger diff --git a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift similarity index 93% rename from Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeClient.swift rename to Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index 46199e98..bbd16efa 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -17,7 +17,7 @@ import NIOCore import NIOHTTP1 import NIOPosix -final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { +final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol { nonisolated let unownedExecutor: UnownedSerialExecutor struct Configuration { @@ -26,9 +26,9 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { } struct Writer: LambdaRuntimeClientResponseStreamWriter { - private var runtimeClient: NewLambdaRuntimeClient + private var runtimeClient: LambdaRuntimeClient - fileprivate init(runtimeClient: NewLambdaRuntimeClient) { + fileprivate init(runtimeClient: LambdaRuntimeClient) { self.runtimeClient = runtimeClient } @@ -51,8 +51,8 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { private enum ConnectionState { case disconnected - case connecting([CheckedContinuation, any Error>]) - case connected(Channel, LambdaChannelHandler) + case connecting([CheckedContinuation, any Error>]) + case connected(Channel, LambdaChannelHandler) } enum LambdaState { @@ -90,9 +90,9 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { configuration: Configuration, eventLoop: any EventLoop, logger: Logger, - _ body: (NewLambdaRuntimeClient) async throws -> Result + _ body: (LambdaRuntimeClient) async throws -> Result ) async throws -> Result { - let runtime = NewLambdaRuntimeClient(configuration: configuration, eventLoop: eventLoop, logger: logger) + let runtime = LambdaRuntimeClient(configuration: configuration, eventLoop: eventLoop, logger: logger) let result: Swift.Result do { result = .success(try await body(runtime)) @@ -130,7 +130,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { case .connecting(let continuations): for continuation in continuations { - continuation.resume(throwing: NewLambdaRuntimeError(code: .closingRuntimeClient)) + continuation.resume(throwing: LambdaRuntimeError(code: .closingRuntimeClient)) } self.connectionState = .connecting([]) @@ -164,7 +164,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { private func write(_ buffer: NIOCore.ByteBuffer) async throws { switch self.lambdaState { case .idle, .sentResponse: - throw NewLambdaRuntimeError(code: .writeAfterFinishHasBeenSent) + throw LambdaRuntimeError(code: .writeAfterFinishHasBeenSent) case .waitingForNextInvocation: fatalError("Invalid state: \(self.lambdaState)") @@ -185,7 +185,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { private func writeAndFinish(_ buffer: NIOCore.ByteBuffer?) async throws { switch self.lambdaState { case .idle, .sentResponse: - throw NewLambdaRuntimeError(code: .finishAfterFinishHasBeenSent) + throw LambdaRuntimeError(code: .finishAfterFinishHasBeenSent) case .waitingForNextInvocation: fatalError("Invalid state: \(self.lambdaState)") @@ -252,7 +252,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { case (.connecting(let array), .notClosing): self.connectionState = .disconnected for continuation in array { - continuation.resume(throwing: NewLambdaRuntimeError(code: .lostConnectionToControlPlane)) + continuation.resume(throwing: LambdaRuntimeError(code: .lostConnectionToControlPlane)) } case (.connecting(let array), .closing(let continuation)): @@ -276,7 +276,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { } } - private func makeOrGetConnection() async throws -> LambdaChannelHandler { + private func makeOrGetConnection() async throws -> LambdaChannelHandler { switch self.connectionState { case .disconnected: self.connectionState = .connecting([]) @@ -285,7 +285,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { // Since we do get sequential invocations this case normally should never be hit. // We'll support it anyway. return try await withCheckedThrowingContinuation { - (continuation: CheckedContinuation, any Error>) in + (continuation: CheckedContinuation, any Error>) in array.append(continuation) self.connectionState = .connecting(array) } @@ -317,7 +317,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { let address = try SocketAddress(ipAddress: self.configuration.ip, port: self.configuration.port) let channel = try await bootstrap.connect(to: address).get() let handler = try channel.pipeline.syncOperations.handler( - type: LambdaChannelHandler.self + type: LambdaChannelHandler.self ) self.logger.trace( "Connection to control plane created", @@ -363,7 +363,7 @@ final actor NewLambdaRuntimeClient: LambdaRuntimeClientProtocol { } } -extension NewLambdaRuntimeClient: LambdaChannelHandlerDelegate { +extension LambdaRuntimeClient: LambdaChannelHandlerDelegate { nonisolated func connectionErrorHappened(_ error: any Error, channel: any Channel) { } @@ -384,7 +384,7 @@ extension NewLambdaRuntimeClient: LambdaChannelHandlerDelegate { } for continuation in continuations { - continuation.resume(throwing: NewLambdaRuntimeError(code: .connectionToControlPlaneLost)) + continuation.resume(throwing: LambdaRuntimeError(code: .connectionToControlPlaneLost)) } case .connected(let stateChannel, _): @@ -433,7 +433,7 @@ private final class LambdaChannelHandler private var reusableErrorBuffer: ByteBuffer? private let logger: Logger private let delegate: Delegate - private let configuration: NewLambdaRuntimeClient.Configuration + private let configuration: LambdaRuntimeClient.Configuration /// These are the default headers that must be sent along an invocation let defaultHeaders: HTTPHeaders @@ -442,7 +442,7 @@ private final class LambdaChannelHandler /// These headers must be sent when streaming a response let streamingHeaders: HTTPHeaders - init(delegate: Delegate, logger: Logger, configuration: NewLambdaRuntimeClient.Configuration) { + init(delegate: Delegate, logger: Logger, configuration: LambdaRuntimeClient.Configuration) { self.delegate = delegate self.logger = logger self.configuration = configuration @@ -479,7 +479,7 @@ private final class LambdaChannelHandler fatalError("Invalid state: \(self.state)") case .disconnected: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneLost) + throw LambdaRuntimeError(code: .connectionToControlPlaneLost) } } @@ -518,10 +518,10 @@ private final class LambdaChannelHandler ) case .disconnected: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneLost) + throw LambdaRuntimeError(code: .connectionToControlPlaneLost) case .closing: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneGoingAway) + throw LambdaRuntimeError(code: .connectionToControlPlaneGoingAway) } } @@ -543,13 +543,13 @@ private final class LambdaChannelHandler case .connected(_, .idle), .connected(_, .sentResponse): - throw NewLambdaRuntimeError(code: .writeAfterFinishHasBeenSent) + throw LambdaRuntimeError(code: .writeAfterFinishHasBeenSent) case .disconnected: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneLost) + throw LambdaRuntimeError(code: .connectionToControlPlaneLost) case .closing: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneGoingAway) + throw LambdaRuntimeError(code: .connectionToControlPlaneGoingAway) } } @@ -576,13 +576,13 @@ private final class LambdaChannelHandler } case .connected(_, .sentResponse): - throw NewLambdaRuntimeError(code: .finishAfterFinishHasBeenSent) + throw LambdaRuntimeError(code: .finishAfterFinishHasBeenSent) case .disconnected: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneLost) + throw LambdaRuntimeError(code: .connectionToControlPlaneLost) case .closing: - throw NewLambdaRuntimeError(code: .connectionToControlPlaneGoingAway) + throw LambdaRuntimeError(code: .connectionToControlPlaneGoingAway) } } @@ -749,7 +749,7 @@ extension LambdaChannelHandler: ChannelInboundHandler { self.delegate.connectionWillClose(channel: context.channel) context.close(promise: nil) continuation.resume( - throwing: NewLambdaRuntimeError(code: .invocationMissingMetadata, underlying: error) + throwing: LambdaRuntimeError(code: .invocationMissingMetadata, underlying: error) ) } @@ -759,7 +759,7 @@ extension LambdaChannelHandler: ChannelInboundHandler { continuation.resume() } else { self.state = .connected(context, .idle) - continuation.resume(throwing: NewLambdaRuntimeError(code: .unexpectedStatusCodeForRequest)) + continuation.resume(throwing: LambdaRuntimeError(code: .unexpectedStatusCodeForRequest)) } case .disconnected, .closing, .connected(_, _): diff --git a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeError.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeError.swift similarity index 96% rename from Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeError.swift rename to Sources/AWSLambdaRuntimeCore/LambdaRuntimeError.swift index 02a4d8b8..a6b4ac66 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambdaRuntimeError.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeError.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -package struct NewLambdaRuntimeError: Error { +package struct LambdaRuntimeError: Error { package enum Code { case closingRuntimeClient diff --git a/Sources/AWSLambdaRuntimeCore/NewLambda+JSON.swift b/Sources/AWSLambdaRuntimeCore/NewLambda+JSON.swift index 4475a81f..b0d6b313 100644 --- a/Sources/AWSLambdaRuntimeCore/NewLambda+JSON.swift +++ b/Sources/AWSLambdaRuntimeCore/NewLambda+JSON.swift @@ -45,32 +45,32 @@ package struct VoidEncoder: LambdaOutputEncoder { package func encode(_ value: Void, into buffer: inout NIOCore.ByteBuffer) throws {} } -/// Adapts a ``NewLambdaHandler`` conforming handler to conform to ``LambdaWithBackgroundProcessingHandler``. +/// Adapts a ``LambdaHandler`` conforming handler to conform to ``LambdaWithBackgroundProcessingHandler``. package struct LambdaHandlerAdapter< Event: Decodable, Output, - Handler: NewLambdaHandler + Handler: LambdaHandler >: LambdaWithBackgroundProcessingHandler where Handler.Event == Event, Handler.Output == Output { @usableFromInline let handler: Handler /// Initializes an instance given a concrete handler. - /// - Parameter handler: The ``NewLambdaHandler`` conforming handler that is to be adapted to ``LambdaWithBackgroundProcessingHandler``. + /// - Parameter handler: The ``LambdaHandler`` conforming handler that is to be adapted to ``LambdaWithBackgroundProcessingHandler``. @inlinable package init(handler: Handler) { self.handler = handler } - /// Passes the generic ``Event`` object to the ``NewLambdaHandler/handle(_:context:)`` function, and + /// Passes the generic ``Event`` object to the ``LambdaHandler/handle(_:context:)`` function, and /// the resulting output is then written to ``LambdaWithBackgroundProcessingHandler``'s `outputWriter`. /// - Parameters: /// - event: The received event. /// - outputWriter: The writer to write the computed response to. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. @inlinable package func handle( _ event: Event, outputWriter: some LambdaResponseWriter, - context: NewLambdaContext + context: LambdaContext ) async throws { let output = try await self.handler.handle(event, context: context) try await outputWriter.write(output) @@ -118,12 +118,12 @@ package struct LambdaCodableAdapter< /// - Parameters: /// - event: The received event. /// - outputWriter: The writer to write the computed response to. - /// - context: The ``NewLambdaContext`` containing the invocation's metadata. + /// - context: The ``LambdaContext`` containing the invocation's metadata. @inlinable package mutating func handle( _ request: ByteBuffer, responseWriter: Writer, - context: NewLambdaContext + context: LambdaContext ) async throws { let event = try self.decoder.decode(Event.self, from: request) diff --git a/Sources/AWSLambdaRuntimeCore/NewLambda.swift b/Sources/AWSLambdaRuntimeCore/NewLambda.swift deleted file mode 100644 index d72df20b..00000000 --- a/Sources/AWSLambdaRuntimeCore/NewLambda.swift +++ /dev/null @@ -1,51 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftAWSLambdaRuntime open source project -// -// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Dispatch -import Logging -import NIOCore - -extension Lambda { - package static func runLoop( - runtimeClient: RuntimeClient, - handler: Handler, - logger: Logger - ) async throws where Handler: StreamingLambdaHandler { - var handler = handler - - while !Task.isCancelled { - let (invocation, writer) = try await runtimeClient.nextInvocation() - - do { - try await handler.handle( - invocation.event, - responseWriter: writer, - context: NewLambdaContext( - requestID: invocation.metadata.requestID, - traceID: invocation.metadata.traceID, - invokedFunctionARN: invocation.metadata.invokedFunctionARN, - deadline: DispatchWallTime(millisSinceEpoch: invocation.metadata.deadlineInMillisSinceEpoch), - logger: logger - ) - ) - } catch { - try await writer.reportError(error) - continue - } - } - } - - /// The default EventLoop the Lambda is scheduled on. - package static var defaultEventLoop: any EventLoop = NIOSingletons.posixEventLoopGroup.next() -} diff --git a/Tests/AWSLambdaRuntimeCoreTests/LambdaRunLoopTests.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRunLoopTests.swift index d85d7f92..741bbf50 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/LambdaRunLoopTests.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaRunLoopTests.swift @@ -25,7 +25,7 @@ struct LambdaRunLoopTests { func handle( _ event: ByteBuffer, responseWriter: some LambdaResponseStreamWriter, - context: NewLambdaContext + context: LambdaContext ) async throws { try await responseWriter.writeAndFinish(event) } @@ -35,7 +35,7 @@ struct LambdaRunLoopTests { func handle( _ event: ByteBuffer, responseWriter: some LambdaResponseStreamWriter, - context: NewLambdaContext + context: LambdaContext ) async throws { throw LambdaError.handlerError } diff --git a/Tests/AWSLambdaRuntimeCoreTests/NewLambdaRuntimeClientTests.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTests.swift similarity index 93% rename from Tests/AWSLambdaRuntimeCoreTests/NewLambdaRuntimeClientTests.swift rename to Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTests.swift index 023c13a0..e779b931 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/NewLambdaRuntimeClientTests.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTests.swift @@ -22,7 +22,7 @@ import struct Foundation.UUID @testable import AWSLambdaRuntimeCore @Suite -struct NewLambdaRuntimeClientTests { +struct LambdaRuntimeClientTests { let logger = { var logger = Logger(label: "NewLambdaClientRuntimeTest") @@ -58,9 +58,9 @@ struct NewLambdaRuntimeClientTests { } try await withMockServer(behaviour: HappyBehavior()) { port in - let configuration = NewLambdaRuntimeClient.Configuration(ip: "127.0.0.1", port: port) + let configuration = LambdaRuntimeClient.Configuration(ip: "127.0.0.1", port: port) - try await NewLambdaRuntimeClient.withRuntimeClient( + try await LambdaRuntimeClient.withRuntimeClient( configuration: configuration, eventLoop: NIOSingletons.posixEventLoopGroup.next(), logger: self.logger diff --git a/Tests/AWSLambdaRuntimeTests/NewLambda+CodableTests.swift b/Tests/AWSLambdaRuntimeTests/NewLambda+CodableTests.swift index 08e55f36..35d56225 100644 --- a/Tests/AWSLambdaRuntimeTests/NewLambda+CodableTests.swift +++ b/Tests/AWSLambdaRuntimeTests/NewLambda+CodableTests.swift @@ -62,7 +62,7 @@ struct JSONTests { let event = ByteBuffer(string: #"{"bar":"baz"}"#) let writer = MockLambdaWriter() - let context = NewLambdaContext.__forTestsOnly( + let context = LambdaContext.__forTestsOnly( requestID: UUID().uuidString, traceID: UUID().uuidString, invokedFunctionARN: "arn:",