Skip to content

Commit 9e32a33

Browse files
committed
async init and @main
1 parent c382d3a commit 9e32a33

File tree

5 files changed

+37
-106
lines changed

5 files changed

+37
-106
lines changed

Sources/AWSLambdaRuntime/Lambda+Codable.swift

-56
Original file line numberDiff line numberDiff line change
@@ -78,62 +78,6 @@ internal struct CodableVoidClosureWrapper<In: Decodable>: LambdaHandler {
7878
}
7979
}
8080

81-
// MARK: - Async
82-
83-
#if compiler(>=5.5) && $AsyncAwait
84-
extension Lambda {
85-
/// Run a Lambda defined by implementing the `CodableAsyncClosure` function.
86-
///
87-
/// - parameters:
88-
/// - closure: `CodableAsyncClosure` based Lambda.
89-
///
90-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
91-
public static func run<In: Decodable, Out: Encodable>(_ closure: @escaping (In, Lambda.Context) async throws -> Out) {
92-
self.run(CodableAsyncWrapper(closure))
93-
}
94-
95-
/// Run a Lambda defined by implementing the `CodableVoidAsyncClosure` function.
96-
///
97-
/// - parameters:
98-
/// - closure: `CodableVoidAsyncClosure` based Lambda.
99-
///
100-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
101-
public static func run<In: Decodable>(_ closure: @escaping (In, Lambda.Context) async throws -> Void) {
102-
self.run(CodableVoidAsyncWrapper(closure))
103-
}
104-
}
105-
106-
internal struct CodableAsyncWrapper<In: Decodable, Out: Encodable>: AsyncLambdaHandler {
107-
typealias In = In
108-
typealias Out = Out
109-
110-
private let closure: (In, Lambda.Context) async throws -> Out
111-
112-
init(_ closure: @escaping (In, Lambda.Context) async throws -> Out) {
113-
self.closure = closure
114-
}
115-
116-
func handle(event: In, context: Lambda.Context) async throws -> Out {
117-
try await self.closure(event, context)
118-
}
119-
}
120-
121-
internal struct CodableVoidAsyncWrapper<In: Decodable>: AsyncLambdaHandler {
122-
typealias In = In
123-
typealias Out = Void
124-
125-
private let closure: (In, Lambda.Context) async throws -> Void
126-
127-
init(_ closure: @escaping (In, Lambda.Context) async throws -> Void) {
128-
self.closure = closure
129-
}
130-
131-
func handle(event: In, context: Lambda.Context) async throws {
132-
try await self.closure(event, context)
133-
}
134-
}
135-
#endif
136-
13781
// MARK: - Codable support
13882

13983
/// Implementation of a`ByteBuffer` to `In` decoding

Sources/AWSLambdaRuntimeCore/Lambda.swift

-12
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,6 @@ public enum Lambda {
5757
}
5858
}
5959

60-
#if compiler(>=5.5) && $AsyncAwait
61-
public static func run(_ factory: @escaping (InitializationContext) async throws -> Handler) {
62-
self.run { context -> EventLoopFuture<Handler> in
63-
let promise = context.eventLoop.makePromise(of: Handler.self)
64-
promise.completeWithAsync {
65-
try await factory(context)
66-
}
67-
return promise.futureResult
68-
}
69-
}
70-
#endif
71-
7260
/// Run a Lambda defined by implementing the `LambdaHandler` protocol provided via a factory, typically a constructor.
7361
///
7462
/// - parameters:

Sources/AWSLambdaRuntimeCore/LambdaHandler.swift

+24-1
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,18 @@ extension LambdaHandler {
8585

8686
// MARK: - AsyncLambdaHandler
8787

88-
#if compiler(>=5.5) && $AsyncAwait
88+
#if compiler(>=5.5)
8989
/// Strongly typed, processing protocol for a Lambda that takes a user defined `In` and returns a user defined `Out` async.
90+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
9091
public protocol AsyncLambdaHandler: EventLoopLambdaHandler {
92+
/// The Lambda initialization method
93+
/// Use this method to initialize resources that will be used in every request.
94+
///
95+
/// Examples for this can be HTTP or database clients.
96+
/// - parameters:
97+
/// - context: Runtime `InitializationContext`.
98+
init(context: Lambda.InitializationContext) async throws
99+
91100
/// The Lambda handling method
92101
/// Concrete Lambda handlers implement this method to provide the Lambda functionality.
93102
///
@@ -99,6 +108,7 @@ public protocol AsyncLambdaHandler: EventLoopLambdaHandler {
99108
func handle(event: In, context: Lambda.Context) async throws -> Out
100109
}
101110

111+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
102112
extension AsyncLambdaHandler {
103113
public func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
104114
let promise = context.eventLoop.makePromise(of: Out.self)
@@ -108,6 +118,19 @@ extension AsyncLambdaHandler {
108118
return promise.futureResult
109119
}
110120
}
121+
122+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
123+
extension AsyncLambdaHandler {
124+
public static func main() {
125+
Lambda.run { context -> EventLoopFuture<ByteBufferLambdaHandler> in
126+
let promise = context.eventLoop.makePromise(of: ByteBufferLambdaHandler.self)
127+
promise.completeWithAsync {
128+
try await Self(context: context)
129+
}
130+
return promise.futureResult
131+
}
132+
}
133+
}
111134
#endif
112135

113136
// MARK: - EventLoopLambdaHandler

Tests/AWSLambdaRuntimeCoreTests/LambdaHandlerTest.swift

+13-4
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@ class LambdaHandlerTest: XCTestCase {
7979
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
8080
}
8181

82-
#if compiler(>=5.5) && $AsyncAwait
82+
#if compiler(>=5.5)
8383

8484
// MARK: - AsyncLambdaHandler
8585

86+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
8687
func testAsyncHandlerSuccess() {
8788
let server = MockLambdaServer(behavior: Behavior())
8889
XCTAssertNoThrow(try server.start().wait())
@@ -92,17 +93,20 @@ class LambdaHandlerTest: XCTestCase {
9293
typealias In = String
9394
typealias Out = String
9495

96+
init(context: Lambda.InitializationContext) {}
97+
9598
func handle(event: String, context: Lambda.Context) async throws -> String {
9699
event
97100
}
98101
}
99102

100103
let maxTimes = Int.random(in: 1 ... 10)
101104
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
102-
let result = Lambda.run(configuration: configuration, handler: Handler())
105+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
103106
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
104107
}
105108

109+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
106110
func testVoidAsyncHandlerSuccess() {
107111
let server = MockLambdaServer(behavior: Behavior(result: .success(nil)))
108112
XCTAssertNoThrow(try server.start().wait())
@@ -112,15 +116,18 @@ class LambdaHandlerTest: XCTestCase {
112116
typealias In = String
113117
typealias Out = Void
114118

119+
init(context: Lambda.InitializationContext) {}
120+
115121
func handle(event: String, context: Lambda.Context) async throws {}
116122
}
117123

118124
let maxTimes = Int.random(in: 1 ... 10)
119125
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
120-
let result = Lambda.run(configuration: configuration, handler: Handler())
126+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
121127
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
122128
}
123129

130+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
124131
func testAsyncHandlerFailure() {
125132
let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom"))))
126133
XCTAssertNoThrow(try server.start().wait())
@@ -130,14 +137,16 @@ class LambdaHandlerTest: XCTestCase {
130137
typealias In = String
131138
typealias Out = String
132139

140+
init(context: Lambda.InitializationContext) {}
141+
133142
func handle(event: String, context: Lambda.Context) async throws -> String {
134143
throw TestError("boom")
135144
}
136145
}
137146

138147
let maxTimes = Int.random(in: 1 ... 10)
139148
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
140-
let result = Lambda.run(configuration: configuration, handler: Handler())
149+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
141150
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
142151
}
143152
#endif

Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift

-33
Original file line numberDiff line numberDiff line change
@@ -63,39 +63,6 @@ class CodableLambdaTest: XCTestCase {
6363
XCTAssertEqual(response?.requestId, request.requestId)
6464
}
6565

66-
#if compiler(>=5.5) && $AsyncAwait
67-
func testCodableVoidAsyncWrapper() {
68-
let request = Request(requestId: UUID().uuidString)
69-
var inputBuffer: ByteBuffer?
70-
var outputBuffer: ByteBuffer?
71-
72-
let closureWrapper = CodableVoidAsyncWrapper { (req: Request, _) in
73-
XCTAssertEqual(request, req)
74-
}
75-
76-
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
77-
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), event: XCTUnwrap(inputBuffer)).wait())
78-
XCTAssertNil(outputBuffer)
79-
}
80-
81-
func testCodableAsyncWrapper() {
82-
let request = Request(requestId: UUID().uuidString)
83-
var inputBuffer: ByteBuffer?
84-
var outputBuffer: ByteBuffer?
85-
var response: Response?
86-
87-
let closureWrapper = CodableAsyncWrapper { (req: Request, _) -> Response in
88-
XCTAssertEqual(req, request)
89-
return Response(requestId: req.requestId)
90-
}
91-
92-
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
93-
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), event: XCTUnwrap(inputBuffer)).wait())
94-
XCTAssertNoThrow(response = try JSONDecoder().decode(Response.self, from: XCTUnwrap(outputBuffer)))
95-
XCTAssertEqual(response?.requestId, request.requestId)
96-
}
97-
#endif
98-
9966
// convencience method
10067
func newContext() -> Lambda.Context {
10168
Lambda.Context(requestID: UUID().uuidString,

0 commit comments

Comments
 (0)