@@ -19,6 +19,7 @@ import NIOConcurrencyHelpers
19
19
extension Lambda {
20
20
public final class Lifecycle {
21
21
private let eventLoop : EventLoop
22
+ private let shutdownPromise : EventLoopPromise < Int >
22
23
private let logger : Logger
23
24
private let configuration : Configuration
24
25
private let factory : LambdaHandlerFactory
@@ -32,6 +33,7 @@ extension Lambda {
32
33
33
34
init ( eventLoop: EventLoop , logger: Logger , configuration: Configuration , factory: @escaping LambdaHandlerFactory ) {
34
35
self . eventLoop = eventLoop
36
+ self . shutdownPromise = eventLoop. makePromise ( of: Int . self)
35
37
self . logger = logger
36
38
self . configuration = configuration
37
39
self . factory = factory
@@ -51,38 +53,43 @@ extension Lambda {
51
53
}
52
54
set {
53
55
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) " )
55
57
self . _state = newValue
56
58
}
59
+ self . logger. debug ( " lambda lifecycle state: \( newValue) " )
57
60
}
58
61
}
59
62
60
- public func start( ) -> EventLoopFuture < Int > {
63
+ public var shutdownFuture : EventLoopFuture < Int > {
64
+ self . shutdownPromise. futureResult
65
+ }
66
+
67
+ public func start( ) -> EventLoopFuture < Void > {
61
68
logger. info ( " lambda lifecycle starting with \( self . configuration) " )
62
69
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)
63
74
var logger = self . logger
64
75
logger [ metadataKey: " lifecycleId " ] = . string( self . configuration. lifecycle. id)
65
76
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
67
78
self . state = . active( runner, handler)
68
- return self . run ( )
79
+ self . run ( promise : promise )
69
80
}
70
81
}
71
82
72
- public func stop( ) {
73
- self . logger. debug ( " lambda lifecycle stopping " )
74
- self . state = . stopping
83
+ public func shutdown( ) {
84
+ self . state = . shuttingdown
75
85
}
76
86
77
- public func shutdown( ) {
78
- self . logger. debug ( " lambda lifecycle shutdown " )
87
+ private func markShutdown( ) {
79
88
self . state = . shutdown
80
89
}
81
90
82
91
@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 > ) {
86
93
func _run( _ count: Int ) {
87
94
switch self . state {
88
95
case . active( let runner, let handler) :
@@ -100,23 +107,21 @@ extension Lambda {
100
107
promise. fail ( error)
101
108
}
102
109
}
103
- case . stopping , . shutdown :
110
+ case . shuttingdown :
104
111
promise. succeed ( count)
105
112
default :
106
113
preconditionFailure ( " invalid run state: \( self . state) " )
107
114
}
108
115
}
109
116
110
117
_run ( 0 )
111
-
112
- return promise. futureResult
113
118
}
114
119
115
120
private enum State {
116
121
case idle
117
122
case initializing
118
123
case active( Runner , ByteBufferLambdaHandler )
119
- case stopping
124
+ case shuttingdown
120
125
case shutdown
121
126
122
127
internal var order : Int {
@@ -127,7 +132,7 @@ extension Lambda {
127
132
return 1
128
133
case . active:
129
134
return 2
130
- case . stopping :
135
+ case . shuttingdown :
131
136
return 3
132
137
case . shutdown:
133
138
return 4
0 commit comments