Skip to content

Commit 71ea055

Browse files
committed
Drop closure APIs
1 parent f01a9b6 commit 71ea055

File tree

13 files changed

+380
-617
lines changed

13 files changed

+380
-617
lines changed

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: 7 additions & 41 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,43 +46,21 @@ 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 {
7652
return nil
7753
}
7854
return String(cString: value)
7955
}
80-
56+
8157
// 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-
}
58+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
59+
internal static func run<Handler: LambdaHandler>(configuration: Configuration = .init(), handlerType: Handler.Type) -> Result<Int, Error> {
60+
self.run(configuration: configuration, factory: { context -> EventLoopFuture<ByteBufferLambdaHandler> in
61+
let promise = context.eventLoop.makePromise(of: ByteBufferLambdaHandler.self)
62+
promise.completeWithTask {
63+
try await Handler(context: context)
9864
}
9965
return promise.futureResult
10066
})

Sources/AWSLambdaRuntimeCore/LambdaHandler.swift

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -18,80 +18,10 @@ import NIOCore
1818

1919
// MARK: - LambdaHandler
2020

21-
/// Strongly typed, callback based processing protocol for a Lambda that takes a user defined `In` and returns a user defined `Out` asynchronously.
22-
/// `LambdaHandler` implements `EventLoopLambdaHandler`, performing callback to `EventLoopFuture` mapping, over a `DispatchQueue` for safety.
23-
///
24-
/// - note: To implement a Lambda, implement either `LambdaHandler` or the `EventLoopLambdaHandler` protocol.
25-
/// The `LambdaHandler` will offload the Lambda execution to a `DispatchQueue` making processing safer but slower.
26-
/// The `EventLoopLambdaHandler` will execute the Lambda on the same `EventLoop` as the core runtime engine, making the processing faster but requires
27-
/// more care from the implementation to never block the `EventLoop`.
28-
public protocol LambdaHandler: EventLoopLambdaHandler {
29-
/// Defines to which `DispatchQueue` the Lambda execution is offloaded to.
30-
var offloadQueue: DispatchQueue { get }
31-
32-
/// The Lambda handling method
33-
/// Concrete Lambda handlers implement this method to provide the Lambda functionality.
34-
///
35-
/// - parameters:
36-
/// - context: Runtime `Context`.
37-
/// - event: Event of type `In` representing the event or request.
38-
/// - callback: Completion handler to report the result of the Lambda back to the runtime engine.
39-
/// The completion handler expects a `Result` with either a response of type `Out` or an `Error`
40-
func handle(context: Lambda.Context, event: In, callback: @escaping (Result<Out, Error>) -> Void)
41-
}
42-
43-
extension Lambda {
44-
@usableFromInline
45-
internal static let defaultOffloadQueue = DispatchQueue(label: "LambdaHandler.offload")
46-
}
47-
48-
extension LambdaHandler {
49-
/// The queue on which `handle` is invoked on.
50-
public var offloadQueue: DispatchQueue {
51-
Lambda.defaultOffloadQueue
52-
}
53-
54-
/// `LambdaHandler` is offloading the processing to a `DispatchQueue`
55-
/// This is slower but safer, in case the implementation blocks the `EventLoop`
56-
/// Performance sensitive Lambdas should be based on `EventLoopLambdaHandler` which does not offload.
57-
@inlinable
58-
public func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
59-
let promise = context.eventLoop.makePromise(of: Out.self)
60-
// FIXME: reusable DispatchQueue
61-
self.offloadQueue.async {
62-
self.handle(context: context, event: event, callback: promise.completeWith)
63-
}
64-
return promise.futureResult
65-
}
66-
}
67-
68-
extension LambdaHandler {
69-
public func shutdown(context: Lambda.ShutdownContext) -> EventLoopFuture<Void> {
70-
let promise = context.eventLoop.makePromise(of: Void.self)
71-
self.offloadQueue.async {
72-
do {
73-
try self.syncShutdown(context: context)
74-
promise.succeed(())
75-
} catch {
76-
promise.fail(error)
77-
}
78-
}
79-
return promise.futureResult
80-
}
81-
82-
/// Clean up the Lambda resources synchronously.
83-
/// Concrete Lambda handlers implement this method to shutdown resources like `HTTPClient`s and database connections.
84-
public func syncShutdown(context: Lambda.ShutdownContext) throws {
85-
// noop
86-
}
87-
}
88-
89-
// MARK: - AsyncLambdaHandler
90-
9121
#if compiler(>=5.5)
9222
/// Strongly typed, processing protocol for a Lambda that takes a user defined `In` and returns a user defined `Out` async.
9323
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
94-
public protocol AsyncLambdaHandler: EventLoopLambdaHandler {
24+
public protocol LambdaHandler: EventLoopLambdaHandler {
9525
/// The Lambda initialization method
9626
/// Use this method to initialize resources that will be used in every request.
9727
///
@@ -112,7 +42,7 @@ public protocol AsyncLambdaHandler: EventLoopLambdaHandler {
11242
}
11343

11444
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
115-
extension AsyncLambdaHandler {
45+
extension LambdaHandler {
11646
public func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
11747
let promise = context.eventLoop.makePromise(of: Out.self)
11848
promise.completeWithTask {
@@ -123,15 +53,9 @@ extension AsyncLambdaHandler {
12353
}
12454

12555
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
126-
extension AsyncLambdaHandler {
56+
extension LambdaHandler {
12757
public static func main() {
128-
Lambda.run { context -> EventLoopFuture<ByteBufferLambdaHandler> in
129-
let promise = context.eventLoop.makePromise(of: ByteBufferLambdaHandler.self)
130-
promise.completeWithTask {
131-
try await Self(context: context)
132-
}
133-
return promise.futureResult
134-
}
58+
_ = Lambda.run(handlerType: Self.self)
13559
}
13660
}
13761
#endif

Sources/AWSLambdaTesting/Lambda+Testing.swift

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,34 +60,6 @@ extension Lambda {
6060
}
6161
}
6262

63-
public static func test(_ closure: @escaping Lambda.StringClosure,
64-
with event: String,
65-
using config: TestConfig = .init()) throws -> String {
66-
try Self.test(StringClosureWrapper(closure), with: event, using: config)
67-
}
68-
69-
public static func test(_ closure: @escaping Lambda.StringVoidClosure,
70-
with event: String,
71-
using config: TestConfig = .init()) throws {
72-
_ = try Self.test(StringVoidClosureWrapper(closure), with: event, using: config)
73-
}
74-
75-
public static func test<In: Decodable, Out: Encodable>(
76-
_ closure: @escaping Lambda.CodableClosure<In, Out>,
77-
with event: In,
78-
using config: TestConfig = .init()
79-
) throws -> Out {
80-
try Self.test(CodableClosureWrapper(closure), with: event, using: config)
81-
}
82-
83-
public static func test<In: Decodable>(
84-
_ closure: @escaping Lambda.CodableVoidClosure<In>,
85-
with event: In,
86-
using config: TestConfig = .init()
87-
) throws {
88-
_ = try Self.test(CodableVoidClosureWrapper(closure), with: event, using: config)
89-
}
90-
9163
public static func test<In, Out, Handler: EventLoopLambdaHandler>(
9264
_ handler: Handler,
9365
with event: In,

Sources/CodableSample/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct Handler: EventLoopLambdaHandler {
3535
}
3636
}
3737

38-
Lambda.run(Handler())
38+
Lambda.run({ $0.eventLoop.makeSucceededFuture(Handler()) })
3939

4040
// MARK: - this can also be expressed as a closure:
4141

Sources/StringSample/main.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,4 @@ struct Handler: EventLoopLambdaHandler {
2626
}
2727
}
2828

29-
Lambda.run(Handler())
30-
31-
// MARK: - this can also be expressed as a closure:
32-
33-
/*
34-
Lambda.run { (_, event: String, callback) in
35-
callback(.success(String(event.reversed())))
36-
}
37-
*/
29+
Lambda.run({ $0.eventLoop.makeSucceededFuture(Handler()) })

0 commit comments

Comments
 (0)