Skip to content

Commit 454fe2e

Browse files
authored
Drop sync and closure APIs (#222)
motivation: with async/await, no need in closure based APIs changes: * Drop closure APIs * Rename AsyncLambdaHandler -> LambdaHandler * Removed unnecassary public acls from tests
1 parent 3511a92 commit 454fe2e

File tree

19 files changed

+394
-610
lines changed

19 files changed

+394
-610
lines changed

Examples/LambdaFunctions/Sources/CurrencyExchange/CurrencyExchangeHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Logging
2424
// MARK: - Run Lambda
2525

2626
@main
27-
struct CurrencyExchangeHandler: AsyncLambdaHandler {
27+
struct CurrencyExchangeHandler: LambdaHandler {
2828
typealias In = Request
2929
typealias Out = [Exchange]
3030

Examples/LambdaFunctions/Sources/ErrorHandling/ErrorsHappenHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AWSLambdaRuntime
1717
// MARK: - Run Lambda
1818

1919
@main
20-
struct ErrorsHappenHandler: AsyncLambdaHandler {
20+
struct ErrorsHappenHandler: LambdaHandler {
2121
typealias In = Request
2222
typealias Out = Response
2323

Examples/LambdaFunctions/Sources/HelloWorld/HelloWorldHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import AWSLambdaRuntime
1616

1717
// introductory example, the obligatory "hello, world!"
1818
@main
19-
struct HelloWorldHandler: AsyncLambdaHandler {
19+
struct HelloWorldHandler: LambdaHandler {
2020
typealias In = String
2121
typealias Out = String
2222

Examples/LocalDebugging/MyLambda/Sources/MyLambda/MyLambdaHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Shared
1818
// set LOCAL_LAMBDA_SERVER_ENABLED env variable to "true" to start
1919
// a local server simulator which will allow local debugging
2020
@main
21-
struct MyLambdaHandler: AsyncLambdaHandler {
21+
struct MyLambdaHandler: LambdaHandler {
2222
typealias In = Request
2323
typealias Out = Response
2424

Sources/AWSLambdaRuntime/Lambda+Codable.swift

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,65 +19,6 @@ import class Foundation.JSONEncoder
1919
import NIOCore
2020
import NIOFoundationCompat
2121

22-
/// Extension to the `Lambda` companion to enable execution of Lambdas that take and return `Codable` events.
23-
extension Lambda {
24-
/// An asynchronous Lambda Closure that takes a `In: Decodable` and returns a `Result<Out: Encodable, Error>` via a completion handler.
25-
public typealias CodableClosure<In: Decodable, Out: Encodable> = (Lambda.Context, In, @escaping (Result<Out, Error>) -> Void) -> Void
26-
27-
/// Run a Lambda defined by implementing the `CodableClosure` function.
28-
///
29-
/// - parameters:
30-
/// - closure: `CodableClosure` based Lambda.
31-
///
32-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
33-
public static func run<In: Decodable, Out: Encodable>(_ closure: @escaping CodableClosure<In, Out>) {
34-
self.run(CodableClosureWrapper(closure))
35-
}
36-
37-
/// An asynchronous Lambda Closure that takes a `In: Decodable` and returns a `Result<Void, Error>` via a completion handler.
38-
public typealias CodableVoidClosure<In: Decodable> = (Lambda.Context, In, @escaping (Result<Void, Error>) -> Void) -> Void
39-
40-
/// Run a Lambda defined by implementing the `CodableVoidClosure` function.
41-
///
42-
/// - parameters:
43-
/// - closure: `CodableVoidClosure` based Lambda.
44-
///
45-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
46-
public static func run<In: Decodable>(_ closure: @escaping CodableVoidClosure<In>) {
47-
self.run(CodableVoidClosureWrapper(closure))
48-
}
49-
}
50-
51-
internal struct CodableClosureWrapper<In: Decodable, Out: Encodable>: LambdaHandler {
52-
typealias In = In
53-
typealias Out = Out
54-
55-
private let closure: Lambda.CodableClosure<In, Out>
56-
57-
init(_ closure: @escaping Lambda.CodableClosure<In, Out>) {
58-
self.closure = closure
59-
}
60-
61-
func handle(context: Lambda.Context, event: In, callback: @escaping (Result<Out, Error>) -> Void) {
62-
self.closure(context, event, callback)
63-
}
64-
}
65-
66-
internal struct CodableVoidClosureWrapper<In: Decodable>: LambdaHandler {
67-
typealias In = In
68-
typealias Out = Void
69-
70-
private let closure: Lambda.CodableVoidClosure<In>
71-
72-
init(_ closure: @escaping Lambda.CodableVoidClosure<In>) {
73-
self.closure = closure
74-
}
75-
76-
func handle(context: Lambda.Context, event: In, callback: @escaping (Result<Out, Error>) -> Void) {
77-
self.closure(context, event, callback)
78-
}
79-
}
80-
8122
// MARK: - Codable support
8223

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

Sources/AWSLambdaRuntimeCore/Lambda+String.swift

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,79 +13,6 @@
1313
//===----------------------------------------------------------------------===//
1414
import NIOCore
1515

16-
/// Extension to the `Lambda` companion to enable execution of Lambdas that take and return `String` events.
17-
extension Lambda {
18-
/// An asynchronous Lambda Closure that takes a `String` and returns a `Result<String, Error>` via a completion handler.
19-
public typealias StringClosure = (Lambda.Context, String, @escaping (Result<String, Error>) -> Void) -> Void
20-
21-
/// Run a Lambda defined by implementing the `StringClosure` function.
22-
///
23-
/// - parameters:
24-
/// - closure: `StringClosure` based Lambda.
25-
///
26-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
27-
public static func run(_ closure: @escaping StringClosure) {
28-
if case .failure(let error) = self.run(closure: closure) {
29-
fatalError("\(error)")
30-
}
31-
}
32-
33-
/// An asynchronous Lambda Closure that takes a `String` and returns a `Result<Void, Error>` via a completion handler.
34-
public typealias StringVoidClosure = (Lambda.Context, String, @escaping (Result<Void, Error>) -> Void) -> Void
35-
36-
/// Run a Lambda defined by implementing the `StringVoidClosure` function.
37-
///
38-
/// - parameters:
39-
/// - closure: `StringVoidClosure` based Lambda.
40-
///
41-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
42-
public static func run(_ closure: @escaping StringVoidClosure) {
43-
if case .failure(let error) = self.run(closure: closure) {
44-
fatalError("\(error)")
45-
}
46-
}
47-
48-
// for testing
49-
internal static func run(configuration: Configuration = .init(), closure: @escaping StringClosure) -> Result<Int, Error> {
50-
self.run(configuration: configuration, handler: StringClosureWrapper(closure))
51-
}
52-
53-
// for testing
54-
internal static func run(configuration: Configuration = .init(), closure: @escaping StringVoidClosure) -> Result<Int, Error> {
55-
self.run(configuration: configuration, handler: StringVoidClosureWrapper(closure))
56-
}
57-
}
58-
59-
internal struct StringClosureWrapper: LambdaHandler {
60-
typealias In = String
61-
typealias Out = String
62-
63-
private let closure: Lambda.StringClosure
64-
65-
init(_ closure: @escaping Lambda.StringClosure) {
66-
self.closure = closure
67-
}
68-
69-
func handle(context: Lambda.Context, event: In, callback: @escaping (Result<Out, Error>) -> Void) {
70-
self.closure(context, event, callback)
71-
}
72-
}
73-
74-
internal struct StringVoidClosureWrapper: LambdaHandler {
75-
typealias In = String
76-
typealias Out = Void
77-
78-
private let closure: Lambda.StringVoidClosure
79-
80-
init(_ closure: @escaping Lambda.StringVoidClosure) {
81-
self.closure = closure
82-
}
83-
84-
func handle(context: Lambda.Context, event: In, callback: @escaping (Result<Out, Error>) -> Void) {
85-
self.closure(context, event, callback)
86-
}
87-
}
88-
8916
extension EventLoopLambdaHandler where In == String {
9017
/// Implementation of a `ByteBuffer` to `String` decoding
9118
@inlinable

Sources/AWSLambdaRuntimeCore/Lambda.swift

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,6 @@ public enum Lambda {
3232
/// A function that takes a `InitializationContext` and returns an `EventLoopFuture` of a `ByteBufferLambdaHandler`
3333
public typealias HandlerFactory = (InitializationContext) -> EventLoopFuture<Handler>
3434

35-
/// Run a Lambda defined by implementing the `LambdaHandler` protocol.
36-
///
37-
/// - parameters:
38-
/// - handler: `ByteBufferLambdaHandler` based Lambda.
39-
///
40-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
41-
public static func run(_ handler: Handler) {
42-
if case .failure(let error) = self.run(handler: handler) {
43-
fatalError("\(error)")
44-
}
45-
}
46-
4735
/// Run a Lambda defined by implementing the `LambdaHandler` protocol provided via a `LambdaHandlerFactory`.
4836
/// Use this to initialize all your resources that you want to cache between invocations. This could be database connections and HTTP clients for example.
4937
/// It is encouraged to use the given `EventLoop`'s conformance to `EventLoopGroup` when initializing NIO dependencies. This will improve overall performance.
@@ -58,18 +46,6 @@ public enum Lambda {
5846
}
5947
}
6048

61-
/// Run a Lambda defined by implementing the `LambdaHandler` protocol provided via a factory, typically a constructor.
62-
///
63-
/// - parameters:
64-
/// - factory: A `ByteBufferLambdaHandler` factory.
65-
///
66-
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
67-
public static func run(_ factory: @escaping (InitializationContext) throws -> Handler) {
68-
if case .failure(let error) = self.run(factory: factory) {
69-
fatalError("\(error)")
70-
}
71-
}
72-
7349
/// Utility to access/read environment variables
7450
public static func env(_ name: String) -> String? {
7551
guard let value = getenv(name) else {
@@ -78,27 +54,19 @@ public enum Lambda {
7854
return String(cString: value)
7955
}
8056

57+
#if swift(>=5.5)
8158
// for testing and internal use
82-
internal static func run(configuration: Configuration = .init(), handler: Handler) -> Result<Int, Error> {
83-
self.run(configuration: configuration, factory: { $0.eventLoop.makeSucceededFuture(handler) })
84-
}
85-
86-
// for testing and internal use
87-
internal static func run(configuration: Configuration = .init(), factory: @escaping (InitializationContext) throws -> Handler) -> Result<Int, Error> {
88-
self.run(configuration: configuration, factory: { context -> EventLoopFuture<Handler> in
89-
let promise = context.eventLoop.makePromise(of: Handler.self)
90-
// if we have a callback based handler factory, we offload the creation of the handler
91-
// onto the default offload queue, to ensure that the eventloop is never blocked.
92-
Lambda.defaultOffloadQueue.async {
93-
do {
94-
promise.succeed(try factory(context))
95-
} catch {
96-
promise.fail(error)
97-
}
59+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
60+
internal static func run<Handler: LambdaHandler>(configuration: Configuration = .init(), handlerType: Handler.Type) -> Result<Int, Error> {
61+
self.run(configuration: configuration, factory: { context -> EventLoopFuture<ByteBufferLambdaHandler> in
62+
let promise = context.eventLoop.makePromise(of: ByteBufferLambdaHandler.self)
63+
promise.completeWithTask {
64+
try await Handler(context: context)
9865
}
9966
return promise.futureResult
10067
})
10168
}
69+
#endif
10270

10371
// for testing and internal use
10472
internal static func run(configuration: Configuration = .init(), factory: @escaping HandlerFactory) -> Result<Int, Error> {

Sources/AWSLambdaRuntimeCore/LambdaContext.swift

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,23 @@ extension Lambda {
3636
/// `ByteBufferAllocator` to allocate `ByteBuffer`
3737
public let allocator: ByteBufferAllocator
3838

39-
internal init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator) {
39+
init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator) {
4040
self.eventLoop = eventLoop
4141
self.logger = logger
4242
self.allocator = allocator
4343
}
44+
45+
/// This interface is not part of the public API and must not be used by adopters. This API is not part of semver versioning.
46+
public static func __forTestsOnly(
47+
logger: Logger,
48+
eventLoop: EventLoop
49+
) -> InitializationContext {
50+
InitializationContext(
51+
logger: logger,
52+
eventLoop: eventLoop,
53+
allocator: ByteBufferAllocator()
54+
)
55+
}
4456
}
4557
}
4658

@@ -138,24 +150,26 @@ extension Lambda {
138150
self.storage.allocator
139151
}
140152

141-
internal init(requestID: String,
142-
traceID: String,
143-
invokedFunctionARN: String,
144-
deadline: DispatchWallTime,
145-
cognitoIdentity: String? = nil,
146-
clientContext: String? = nil,
147-
logger: Logger,
148-
eventLoop: EventLoop,
149-
allocator: ByteBufferAllocator) {
150-
self.storage = _Storage(requestID: requestID,
151-
traceID: traceID,
152-
invokedFunctionARN: invokedFunctionARN,
153-
deadline: deadline,
154-
cognitoIdentity: cognitoIdentity,
155-
clientContext: clientContext,
156-
logger: logger,
157-
eventLoop: eventLoop,
158-
allocator: allocator)
153+
init(requestID: String,
154+
traceID: String,
155+
invokedFunctionARN: String,
156+
deadline: DispatchWallTime,
157+
cognitoIdentity: String? = nil,
158+
clientContext: String? = nil,
159+
logger: Logger,
160+
eventLoop: EventLoop,
161+
allocator: ByteBufferAllocator) {
162+
self.storage = _Storage(
163+
requestID: requestID,
164+
traceID: traceID,
165+
invokedFunctionARN: invokedFunctionARN,
166+
deadline: deadline,
167+
cognitoIdentity: cognitoIdentity,
168+
clientContext: clientContext,
169+
logger: logger,
170+
eventLoop: eventLoop,
171+
allocator: allocator
172+
)
159173
}
160174

161175
public func getRemainingTime() -> TimeAmount {
@@ -169,6 +183,26 @@ extension Lambda {
169183
public var debugDescription: String {
170184
"\(Self.self)(requestID: \(self.requestID), traceID: \(self.traceID), invokedFunctionARN: \(self.invokedFunctionARN), cognitoIdentity: \(self.cognitoIdentity ?? "nil"), clientContext: \(self.clientContext ?? "nil"), deadline: \(self.deadline))"
171185
}
186+
187+
/// This interface is not part of the public API and must not be used by adopters. This API is not part of semver versioning.
188+
public static func __forTestsOnly(
189+
requestID: String,
190+
traceID: String,
191+
invokedFunctionARN: String,
192+
timeout: DispatchTimeInterval,
193+
logger: Logger,
194+
eventLoop: EventLoop
195+
) -> Context {
196+
Context(
197+
requestID: requestID,
198+
traceID: traceID,
199+
invokedFunctionARN: invokedFunctionARN,
200+
deadline: .now() + timeout,
201+
logger: logger,
202+
eventLoop: eventLoop,
203+
allocator: ByteBufferAllocator()
204+
)
205+
}
172206
}
173207
}
174208

0 commit comments

Comments
 (0)