Skip to content

Commit 7d1da8c

Browse files
committed
make lifecycle safer to user as a public api
1 parent 23c7471 commit 7d1da8c

File tree

3 files changed

+29
-22
lines changed

3 files changed

+29
-22
lines changed

Sources/AWSLambdaRuntime/Lambda.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ public enum Lambda {
8383
let lifecycle = Lifecycle(eventLoop: eventLoopGroup.next(), logger: logger, configuration: configuration, factory: factory)
8484
let signalSource = trap(signal: configuration.lifecycle.stopSignal) { signal in
8585
logger.info("intercepted signal: \(signal)")
86-
lifecycle.stop()
87-
}
88-
return lifecycle.start().always { _ in
8986
lifecycle.shutdown()
90-
signalSource.cancel()
87+
}
88+
return lifecycle.start().flatMap {
89+
return lifecycle.shutdownFuture.always { _ in
90+
signalSource.cancel()
91+
}
9192
}
9293
}
9394
}

Sources/AWSLambdaRuntime/LambdaLifecycle.swift

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import NIOConcurrencyHelpers
1919
extension Lambda {
2020
public final class Lifecycle {
2121
private let eventLoop: EventLoop
22+
private let shutdownPromise: EventLoopPromise<Int>
2223
private let logger: Logger
2324
private let configuration: Configuration
2425
private let factory: LambdaHandlerFactory
@@ -32,6 +33,7 @@ extension Lambda {
3233

3334
init(eventLoop: EventLoop, logger: Logger, configuration: Configuration, factory: @escaping LambdaHandlerFactory) {
3435
self.eventLoop = eventLoop
36+
self.shutdownPromise = eventLoop.makePromise(of: Int.self)
3537
self.logger = logger
3638
self.configuration = configuration
3739
self.factory = factory
@@ -51,38 +53,43 @@ extension Lambda {
5153
}
5254
set {
5355
self.stateLock.withLockVoid {
54-
precondition(newValue.order > _state.order, "invalid state \(newValue) after \(self._state)")
56+
precondition(newValue.order > self._state.order, "invalid state \(newValue) after \(self._state)")
5557
self._state = newValue
5658
}
59+
self.logger.debug("lambda lifecycle state: \(newValue)")
5760
}
5861
}
5962

60-
public func start() -> EventLoopFuture<Int> {
63+
public var shutdownFuture: EventLoopFuture<Int> {
64+
self.shutdownPromise.futureResult
65+
}
66+
67+
public func start() -> EventLoopFuture<Void> {
6168
logger.info("lambda lifecycle starting with \(self.configuration)")
6269
self.state = .initializing
70+
let promise = self.eventLoop.makePromise(of: Int.self)
71+
promise.futureResult.always { _ in
72+
self.markShutdown()
73+
}.cascade(to: self.shutdownPromise)
6374
var logger = self.logger
6475
logger[metadataKey: "lifecycleId"] = .string(self.configuration.lifecycle.id)
6576
let runner = Runner(eventLoop: self.eventLoop, configuration: self.configuration)
66-
return runner.initialize(logger: logger, factory: self.factory).flatMap { handler in
77+
return runner.initialize(logger: logger, factory: self.factory).map { handler in
6778
self.state = .active(runner, handler)
68-
return self.run()
79+
self.run(promise: promise)
6980
}
7081
}
7182

72-
public func stop() {
73-
self.logger.debug("lambda lifecycle stopping")
74-
self.state = .stopping
83+
public func shutdown() {
84+
self.state = .shuttingdown
7585
}
7686

77-
public func shutdown() {
78-
self.logger.debug("lambda lifecycle shutdown")
87+
private func markShutdown() {
7988
self.state = .shutdown
8089
}
8190

8291
@inline(__always)
83-
private func run() -> EventLoopFuture<Int> {
84-
let promise = self.eventLoop.makePromise(of: Int.self)
85-
92+
private func run(promise: EventLoopPromise<Int>) {
8693
func _run(_ count: Int) {
8794
switch self.state {
8895
case .active(let runner, let handler):
@@ -100,23 +107,21 @@ extension Lambda {
100107
promise.fail(error)
101108
}
102109
}
103-
case .stopping, .shutdown:
110+
case .shuttingdown:
104111
promise.succeed(count)
105112
default:
106113
preconditionFailure("invalid run state: \(self.state)")
107114
}
108115
}
109116

110117
_run(0)
111-
112-
return promise.futureResult
113118
}
114119

115120
private enum State {
116121
case idle
117122
case initializing
118123
case active(Runner, ByteBufferLambdaHandler)
119-
case stopping
124+
case shuttingdown
120125
case shutdown
121126

122127
internal var order: Int {
@@ -127,7 +132,7 @@ extension Lambda {
127132
return 1
128133
case .active:
129134
return 2
130-
case .stopping:
135+
case .shuttingdown:
131136
return 3
132137
case .shutdown:
133138
return 4

Sources/StringSample/main.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15+
import AWSLambdaEvents
1516
import AWSLambdaRuntime
1617
import NIO
1718

@@ -20,7 +21,7 @@ struct Handler: EventLoopLambdaHandler {
2021
typealias In = String
2122
typealias Out = String
2223

23-
func handle(context: Lambda.Context, payload: String) -> EventLoopFuture<String> {
24+
func handle(context: Lambda.Context, payload: In) -> EventLoopFuture<Out> {
2425
// as an example, respond with the reverse the input payload
2526
context.eventLoop.makeSucceededFuture(String(payload.reversed()))
2627
}

0 commit comments

Comments
 (0)