Skip to content

Commit 14d96bd

Browse files
committed
async init and @main
1 parent c382d3a commit 14d96bd

File tree

5 files changed

+30
-94
lines changed

5 files changed

+30
-94
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public enum Lambda {
5858
}
5959

6060
#if compiler(>=5.5) && $AsyncAwait
61-
public static func run(_ factory: @escaping (InitializationContext) async throws -> Handler) {
61+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
62+
internal static func run(_ factory: @escaping (InitializationContext) async throws -> Handler) {
6263
self.run { context -> EventLoopFuture<Handler> in
6364
let promise = context.eventLoop.makePromise(of: Handler.self)
6465
promise.completeWithAsync {

Sources/AWSLambdaRuntimeCore/LambdaHandler.swift

+19-1
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,19 @@ 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+
93+
/// The Lambda initialization method
94+
/// Use this method to initialize resources that will be used in every request.
95+
///
96+
/// Examples for this can be HTTP or database clients.
97+
/// - parameters:
98+
/// - context: Runtime `InitializationContext`.
99+
init(context: Lambda.InitializationContext) async throws
100+
91101
/// The Lambda handling method
92102
/// Concrete Lambda handlers implement this method to provide the Lambda functionality.
93103
///
@@ -99,6 +109,7 @@ public protocol AsyncLambdaHandler: EventLoopLambdaHandler {
99109
func handle(event: In, context: Lambda.Context) async throws -> Out
100110
}
101111

112+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
102113
extension AsyncLambdaHandler {
103114
public func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
104115
let promise = context.eventLoop.makePromise(of: Out.self)
@@ -108,6 +119,13 @@ extension AsyncLambdaHandler {
108119
return promise.futureResult
109120
}
110121
}
122+
123+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
124+
extension AsyncLambdaHandler {
125+
public static func main() {
126+
Lambda.run(Self.init)
127+
}
128+
}
111129
#endif
112130

113131
// MARK: - EventLoopLambdaHandler

Tests/AWSLambdaRuntimeCoreTests/LambdaHandlerTest.swift

+9-3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class LambdaHandlerTest: XCTestCase {
9191
struct Handler: AsyncLambdaHandler {
9292
typealias In = String
9393
typealias Out = String
94+
95+
init(context: Lambda.InitializationContext) {}
9496

9597
func handle(event: String, context: Lambda.Context) async throws -> String {
9698
event
@@ -99,7 +101,7 @@ class LambdaHandlerTest: XCTestCase {
99101

100102
let maxTimes = Int.random(in: 1 ... 10)
101103
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
102-
let result = Lambda.run(configuration: configuration, handler: Handler())
104+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
103105
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
104106
}
105107

@@ -111,13 +113,15 @@ class LambdaHandlerTest: XCTestCase {
111113
struct Handler: AsyncLambdaHandler {
112114
typealias In = String
113115
typealias Out = Void
116+
117+
init(context: Lambda.InitializationContext) {}
114118

115119
func handle(event: String, context: Lambda.Context) async throws {}
116120
}
117121

118122
let maxTimes = Int.random(in: 1 ... 10)
119123
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
120-
let result = Lambda.run(configuration: configuration, handler: Handler())
124+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
121125
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
122126
}
123127

@@ -129,6 +133,8 @@ class LambdaHandlerTest: XCTestCase {
129133
struct Handler: AsyncLambdaHandler {
130134
typealias In = String
131135
typealias Out = String
136+
137+
init(context: Lambda.InitializationContext) {}
132138

133139
func handle(event: String, context: Lambda.Context) async throws -> String {
134140
throw TestError("boom")
@@ -137,7 +143,7 @@ class LambdaHandlerTest: XCTestCase {
137143

138144
let maxTimes = Int.random(in: 1 ... 10)
139145
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
140-
let result = Lambda.run(configuration: configuration, handler: Handler())
146+
let result = Lambda.run(configuration: configuration, factory: Handler.init)
141147
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
142148
}
143149
#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)