From e4c72d80ab7339a9813e06ef1b0383d2fbdb6a13 Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Wed, 14 Apr 2021 18:37:41 +0200 Subject: [PATCH] Inline default `LambdaHandler` implementations --- Sources/AWSLambdaRuntime/Lambda+Codable.swift | 2 + .../AWSLambdaRuntimeCore/Lambda+String.swift | 2 + .../AWSLambdaRuntimeCore/LambdaHandler.swift | 40 +++++++------------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift index 99ab7175..620c52e2 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -80,6 +80,7 @@ internal struct CodableVoidClosureWrapper: LambdaHandler { /// Implementation of a`ByteBuffer` to `In` decoding extension EventLoopLambdaHandler where In: Decodable { + @inlinable public func decode(buffer: ByteBuffer) throws -> In { try self.decoder.decode(In.self, from: buffer) } @@ -87,6 +88,7 @@ extension EventLoopLambdaHandler where In: Decodable { /// Implementation of `Out` to `ByteBuffer` encoding extension EventLoopLambdaHandler where Out: Encodable { + @inlinable public func encode(allocator: ByteBufferAllocator, value: Out) throws -> ByteBuffer? { try self.encoder.encode(value, using: allocator) } diff --git a/Sources/AWSLambdaRuntimeCore/Lambda+String.swift b/Sources/AWSLambdaRuntimeCore/Lambda+String.swift index ee6f9f84..c6ceda6a 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda+String.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda+String.swift @@ -88,6 +88,7 @@ internal struct StringVoidClosureWrapper: LambdaHandler { extension EventLoopLambdaHandler where In == String { /// Implementation of a `ByteBuffer` to `String` decoding + @inlinable public func decode(buffer: ByteBuffer) throws -> String { var buffer = buffer guard let string = buffer.readString(length: buffer.readableBytes) else { @@ -99,6 +100,7 @@ extension EventLoopLambdaHandler where In == String { extension EventLoopLambdaHandler where Out == String { /// Implementation of `String` to `ByteBuffer` encoding + @inlinable public func encode(allocator: ByteBufferAllocator, value: String) throws -> ByteBuffer? { // FIXME: reusable buffer var buffer = allocator.buffer(capacity: value.utf8.count) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift b/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift index 87c8c102..008620d8 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift @@ -40,6 +40,7 @@ public protocol LambdaHandler: EventLoopLambdaHandler { } extension Lambda { + @usableFromInline internal static let defaultOffloadQueue = DispatchQueue(label: "LambdaHandler.offload") } @@ -52,6 +53,7 @@ extension LambdaHandler { /// `LambdaHandler` is offloading the processing to a `DispatchQueue` /// This is slower but safer, in case the implementation blocks the `EventLoop` /// Performance sensitive Lambdas should be based on `EventLoopLambdaHandler` which does not offload. + @inlinable public func handle(context: Lambda.Context, event: In) -> EventLoopFuture { let promise = context.eventLoop.makePromise(of: Out.self) // FIXME: reusable DispatchQueue @@ -128,41 +130,28 @@ public protocol EventLoopLambdaHandler: ByteBufferLambdaHandler { extension EventLoopLambdaHandler { /// Driver for `ByteBuffer` -> `In` decoding and `Out` -> `ByteBuffer` encoding + @inlinable public func handle(context: Lambda.Context, event: ByteBuffer) -> EventLoopFuture { - switch self.decodeIn(buffer: event) { - case .failure(let error): - return context.eventLoop.makeFailedFuture(CodecError.requestDecoding(error)) - case .success(let `in`): - return self.handle(context: context, event: `in`).flatMapThrowing { out in - switch self.encodeOut(allocator: context.allocator, value: out) { - case .failure(let error): - throw CodecError.responseEncoding(error) - case .success(let buffer): - return buffer - } - } - } - } - - private func decodeIn(buffer: ByteBuffer) -> Result { + let input: In do { - return .success(try self.decode(buffer: buffer)) + input = try self.decode(buffer: event) } catch { - return .failure(error) + return context.eventLoop.makeFailedFuture(CodecError.requestDecoding(error)) } - } - private func encodeOut(allocator: ByteBufferAllocator, value: Out) -> Result { - do { - return .success(try self.encode(allocator: allocator, value: value)) - } catch { - return .failure(error) + return self.handle(context: context, event: input).flatMapThrowing { output in + do { + return try self.encode(allocator: context.allocator, value: output) + } catch { + throw CodecError.responseEncoding(error) + } } } } /// Implementation of `ByteBuffer` to `Void` decoding extension EventLoopLambdaHandler where Out == Void { + @inlinable public func encode(allocator: ByteBufferAllocator, value: Void) throws -> ByteBuffer? { nil } @@ -200,7 +189,8 @@ extension ByteBufferLambdaHandler { } } -private enum CodecError: Error { +@usableFromInline +enum CodecError: Error { case requestDecoding(Error) case responseEncoding(Error) }