Skip to content

Commit 19a9f92

Browse files
authored
Inline default LambdaHandler implementations (#201)
Add `@inlinable` to default LambdaHandler implementations. This ensures that those implementations can be inlined into user code and can be specialized for their input and output types.
1 parent ab13e51 commit 19a9f92

File tree

3 files changed

+19
-25
lines changed

3 files changed

+19
-25
lines changed

Sources/AWSLambdaRuntime/Lambda+Codable.swift

+2
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,15 @@ internal struct CodableVoidClosureWrapper<In: Decodable>: LambdaHandler {
8080

8181
/// Implementation of a`ByteBuffer` to `In` decoding
8282
extension EventLoopLambdaHandler where In: Decodable {
83+
@inlinable
8384
public func decode(buffer: ByteBuffer) throws -> In {
8485
try self.decoder.decode(In.self, from: buffer)
8586
}
8687
}
8788

8889
/// Implementation of `Out` to `ByteBuffer` encoding
8990
extension EventLoopLambdaHandler where Out: Encodable {
91+
@inlinable
9092
public func encode(allocator: ByteBufferAllocator, value: Out) throws -> ByteBuffer? {
9193
try self.encoder.encode(value, using: allocator)
9294
}

Sources/AWSLambdaRuntimeCore/Lambda+String.swift

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ internal struct StringVoidClosureWrapper: LambdaHandler {
8888

8989
extension EventLoopLambdaHandler where In == String {
9090
/// Implementation of a `ByteBuffer` to `String` decoding
91+
@inlinable
9192
public func decode(buffer: ByteBuffer) throws -> String {
9293
var buffer = buffer
9394
guard let string = buffer.readString(length: buffer.readableBytes) else {
@@ -99,6 +100,7 @@ extension EventLoopLambdaHandler where In == String {
99100

100101
extension EventLoopLambdaHandler where Out == String {
101102
/// Implementation of `String` to `ByteBuffer` encoding
103+
@inlinable
102104
public func encode(allocator: ByteBufferAllocator, value: String) throws -> ByteBuffer? {
103105
// FIXME: reusable buffer
104106
var buffer = allocator.buffer(capacity: value.utf8.count)

Sources/AWSLambdaRuntimeCore/LambdaHandler.swift

+15-25
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public protocol LambdaHandler: EventLoopLambdaHandler {
4040
}
4141

4242
extension Lambda {
43+
@usableFromInline
4344
internal static let defaultOffloadQueue = DispatchQueue(label: "LambdaHandler.offload")
4445
}
4546

@@ -52,6 +53,7 @@ extension LambdaHandler {
5253
/// `LambdaHandler` is offloading the processing to a `DispatchQueue`
5354
/// This is slower but safer, in case the implementation blocks the `EventLoop`
5455
/// Performance sensitive Lambdas should be based on `EventLoopLambdaHandler` which does not offload.
56+
@inlinable
5557
public func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
5658
let promise = context.eventLoop.makePromise(of: Out.self)
5759
// FIXME: reusable DispatchQueue
@@ -128,41 +130,28 @@ public protocol EventLoopLambdaHandler: ByteBufferLambdaHandler {
128130

129131
extension EventLoopLambdaHandler {
130132
/// Driver for `ByteBuffer` -> `In` decoding and `Out` -> `ByteBuffer` encoding
133+
@inlinable
131134
public func handle(context: Lambda.Context, event: ByteBuffer) -> EventLoopFuture<ByteBuffer?> {
132-
switch self.decodeIn(buffer: event) {
133-
case .failure(let error):
134-
return context.eventLoop.makeFailedFuture(CodecError.requestDecoding(error))
135-
case .success(let `in`):
136-
return self.handle(context: context, event: `in`).flatMapThrowing { out in
137-
switch self.encodeOut(allocator: context.allocator, value: out) {
138-
case .failure(let error):
139-
throw CodecError.responseEncoding(error)
140-
case .success(let buffer):
141-
return buffer
142-
}
143-
}
144-
}
145-
}
146-
147-
private func decodeIn(buffer: ByteBuffer) -> Result<In, Error> {
135+
let input: In
148136
do {
149-
return .success(try self.decode(buffer: buffer))
137+
input = try self.decode(buffer: event)
150138
} catch {
151-
return .failure(error)
139+
return context.eventLoop.makeFailedFuture(CodecError.requestDecoding(error))
152140
}
153-
}
154141

155-
private func encodeOut(allocator: ByteBufferAllocator, value: Out) -> Result<ByteBuffer?, Error> {
156-
do {
157-
return .success(try self.encode(allocator: allocator, value: value))
158-
} catch {
159-
return .failure(error)
142+
return self.handle(context: context, event: input).flatMapThrowing { output in
143+
do {
144+
return try self.encode(allocator: context.allocator, value: output)
145+
} catch {
146+
throw CodecError.responseEncoding(error)
147+
}
160148
}
161149
}
162150
}
163151

164152
/// Implementation of `ByteBuffer` to `Void` decoding
165153
extension EventLoopLambdaHandler where Out == Void {
154+
@inlinable
166155
public func encode(allocator: ByteBufferAllocator, value: Void) throws -> ByteBuffer? {
167156
nil
168157
}
@@ -200,7 +189,8 @@ extension ByteBufferLambdaHandler {
200189
}
201190
}
202191

203-
private enum CodecError: Error {
192+
@usableFromInline
193+
enum CodecError: Error {
204194
case requestDecoding(Error)
205195
case responseEncoding(Error)
206196
}

0 commit comments

Comments
 (0)