-
Notifications
You must be signed in to change notification settings - Fork 113
Allow integration with API Frameworks: Public Lifecycle #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,17 +17,23 @@ import NIO | |
import NIOConcurrencyHelpers | ||
|
||
extension Lambda { | ||
internal final class Lifecycle { | ||
public final class Lifecycle { | ||
private let eventLoop: EventLoop | ||
private let shutdownPromise: EventLoopPromise<Int> | ||
private let logger: Logger | ||
private let configuration: Configuration | ||
private let factory: LambdaHandlerFactory | ||
|
||
private var _state = State.idle | ||
private let stateLock = Lock() | ||
|
||
public convenience init(eventLoop: EventLoop, logger: Logger, factory: @escaping LambdaHandlerFactory) { | ||
self.init(eventLoop: eventLoop, logger: logger, configuration: .init(), factory: factory) | ||
} | ||
|
||
init(eventLoop: EventLoop, logger: Logger, configuration: Configuration, factory: @escaping LambdaHandlerFactory) { | ||
self.eventLoop = eventLoop | ||
self.shutdownPromise = eventLoop.makePromise(of: Int.self) | ||
self.logger = logger | ||
self.configuration = configuration | ||
self.factory = factory | ||
|
@@ -47,38 +53,43 @@ extension Lambda { | |
} | ||
set { | ||
self.stateLock.withLockVoid { | ||
precondition(newValue.order > _state.order, "invalid state \(newValue) after \(self._state)") | ||
precondition(newValue.order > self._state.order, "invalid state \(newValue) after \(self._state)") | ||
self._state = newValue | ||
} | ||
self.logger.debug("lambda lifecycle state: \(newValue)") | ||
} | ||
} | ||
|
||
func start() -> EventLoopFuture<Int> { | ||
public var shutdownFuture: EventLoopFuture<Int> { | ||
self.shutdownPromise.futureResult | ||
} | ||
|
||
public func start() -> EventLoopFuture<Void> { | ||
logger.info("lambda lifecycle starting with \(self.configuration)") | ||
self.state = .initializing | ||
let promise = self.eventLoop.makePromise(of: Int.self) | ||
tomerd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
promise.futureResult.always { _ in | ||
self.markShutdown() | ||
}.cascade(to: self.shutdownPromise) | ||
var logger = self.logger | ||
logger[metadataKey: "lifecycleId"] = .string(self.configuration.lifecycle.id) | ||
let runner = Runner(eventLoop: self.eventLoop, configuration: self.configuration) | ||
return runner.initialize(logger: logger, factory: self.factory).flatMap { handler in | ||
return runner.initialize(logger: logger, factory: self.factory).map { handler in | ||
self.state = .active(runner, handler) | ||
return self.run() | ||
self.run(promise: promise) | ||
} | ||
} | ||
|
||
func stop() { | ||
self.logger.debug("lambda lifecycle stopping") | ||
self.state = .stopping | ||
public func shutdown() { | ||
self.state = .shuttingdown | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should wrap this in an eventLoop.submit {
self.state = .shuttingdown
} to ensure needed thread safety. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. state is protected with lock, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You‘re right. Sorry. |
||
} | ||
|
||
func shutdown() { | ||
self.logger.debug("lambda lifecycle shutdown") | ||
private func markShutdown() { | ||
self.state = .shutdown | ||
} | ||
|
||
@inline(__always) | ||
private func run() -> EventLoopFuture<Int> { | ||
let promise = self.eventLoop.makePromise(of: Int.self) | ||
|
||
private func run(promise: EventLoopPromise<Int>) { | ||
func _run(_ count: Int) { | ||
switch self.state { | ||
case .active(let runner, let handler): | ||
|
@@ -96,23 +107,21 @@ extension Lambda { | |
promise.fail(error) | ||
} | ||
} | ||
case .stopping, .shutdown: | ||
case .shuttingdown: | ||
promise.succeed(count) | ||
default: | ||
preconditionFailure("invalid run state: \(self.state)") | ||
} | ||
} | ||
|
||
_run(0) | ||
|
||
return promise.futureResult | ||
} | ||
|
||
private enum State { | ||
case idle | ||
case initializing | ||
case active(Runner, ByteBufferLambdaHandler) | ||
case stopping | ||
case shuttingdown | ||
case shutdown | ||
|
||
internal var order: Int { | ||
|
@@ -123,7 +132,7 @@ extension Lambda { | |
return 1 | ||
case .active: | ||
return 2 | ||
case .stopping: | ||
case .shuttingdown: | ||
return 3 | ||
case .shutdown: | ||
return 4 | ||
|
Uh oh!
There was an error while loading. Please reload this page.