Skip to content

Commit 19c5224

Browse files
authored
update api to remove Lifecycle psuedo namespace (#40)
motivation: address api feedback, do not clash module and type names changes: * remove top level Lifecycle psuedo namespace (enum) * rename Lifecycle.Task to LifecyclTask * rename Lifecycle.Handler to LifecycleHandler
1 parent d18349b commit 19c5224

File tree

5 files changed

+107
-113
lines changed

5 files changed

+107
-113
lines changed

Sources/Lifecycle/Lifecycle.swift

Lines changed: 90 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ import Backtrace
2121
import Dispatch
2222
import Logging
2323

24-
// MARK: - Lifecycle (namespace)
25-
26-
public enum Lifecycle {
27-
public typealias Task = LifecycleTask
28-
}
24+
// MARK: - LifecycleTask
2925

3026
/// Represents an item that can be started and shut down
3127
public protocol LifecycleTask {
@@ -34,87 +30,52 @@ public protocol LifecycleTask {
3430
func shutdown(_ callback: @escaping (Error?) -> Void)
3531
}
3632

37-
/// Supported startup and shutdown method styles
38-
public extension Lifecycle {
39-
struct Handler {
40-
private let body: (@escaping (Error?) -> Void) -> Void
41-
42-
/// Initialize a `Lifecycle.Handler` based on a completion handler.
43-
///
44-
/// - parameters:
45-
/// - callback: the underlying completion handler
46-
public init(_ callback: @escaping (@escaping (Error?) -> Void) -> Void) {
47-
self.body = callback
48-
}
49-
50-
/// Asynchronous `Lifecycle.Handler` based on a completion handler.
51-
///
52-
/// - parameters:
53-
/// - callback: the underlying completion handler
54-
public static func async(_ callback: @escaping (@escaping (Error?) -> Void) -> Void) -> Handler {
55-
return Handler(callback)
56-
}
57-
58-
/// Asynchronous `Lifecycle.Handler` based on a blocking, throwing function.
59-
///
60-
/// - parameters:
61-
/// - body: the underlying function
62-
public static func sync(_ body: @escaping () throws -> Void) -> Handler {
63-
return Handler { completionHandler in
64-
do {
65-
try body()
66-
completionHandler(nil)
67-
} catch {
68-
completionHandler(error)
69-
}
70-
}
71-
}
33+
// MARK: - LifecycleHandler
7234

73-
/// Noop `Lifecycle.Handler`.
74-
public static var none: Handler {
75-
return Handler { callback in
76-
callback(nil)
77-
}
78-
}
35+
/// Supported startup and shutdown method styles
36+
public struct LifecycleHandler {
37+
private let body: (@escaping (Error?) -> Void) -> Void
7938

80-
internal func run(_ callback: @escaping (Error?) -> Void) {
81-
self.body(callback)
82-
}
39+
/// Initialize a `Lifecycle.Handler` based on a completion handler.
40+
///
41+
/// - parameters:
42+
/// - callback: the underlying completion handler
43+
public init(_ callback: @escaping (@escaping (Error?) -> Void) -> Void) {
44+
self.body = callback
8345
}
84-
}
8546

86-
public extension Lifecycle {
87-
struct ShutdownError: Error {
88-
public let errors: [String: Error]
47+
/// Asynchronous `Lifecycle.Handler` based on a completion handler.
48+
///
49+
/// - parameters:
50+
/// - callback: the underlying completion handler
51+
public static func async(_ callback: @escaping (@escaping (Error?) -> Void) -> Void) -> LifecycleHandler {
52+
return LifecycleHandler(callback)
8953
}
90-
}
9154

92-
extension Lifecycle {
93-
/// Setup a signal trap.
55+
/// Asynchronous `Lifecycle.Handler` based on a blocking, throwing function.
9456
///
9557
/// - parameters:
96-
/// - signal: The signal to trap.
97-
/// - handler: closure to invoke when the signal is captured.
98-
/// - returns: a `DispatchSourceSignal` for the given trap. The source must be cancled by the caller.
99-
public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global()) -> DispatchSourceSignal {
100-
let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue)
101-
signal(sig.rawValue, SIG_IGN)
102-
signalSource.setEventHandler(handler: {
103-
signalSource.cancel()
104-
handler(sig)
105-
})
106-
signalSource.resume()
107-
return signalSource
58+
/// - body: the underlying function
59+
public static func sync(_ body: @escaping () throws -> Void) -> LifecycleHandler {
60+
return LifecycleHandler { completionHandler in
61+
do {
62+
try body()
63+
completionHandler(nil)
64+
} catch {
65+
completionHandler(error)
66+
}
67+
}
10868
}
10969

110-
/// A system signal
111-
public struct Signal {
112-
internal var rawValue: CInt
70+
/// Noop `Lifecycle.Handler`.
71+
public static var none: LifecycleHandler {
72+
return LifecycleHandler { callback in
73+
callback(nil)
74+
}
75+
}
11376

114-
public static let TERM: Signal = Signal(rawValue: SIGTERM)
115-
public static let INT: Signal = Signal(rawValue: SIGINT)
116-
// for testing
117-
internal static let ALRM: Signal = Signal(rawValue: SIGALRM)
77+
internal func run(_ callback: @escaping (Error?) -> Void) {
78+
self.body(callback)
11879
}
11980
}
12081

@@ -146,7 +107,7 @@ public struct ServiceLifecycle {
146107
public func start(_ callback: @escaping (Error?) -> Void) {
147108
self.configuration.shutdownSignal?.forEach { signal in
148109
self.lifecycle.log("setting up shutdown hook on \(signal)")
149-
let signalSource = Lifecycle.trap(signal: signal, handler: { signal in
110+
let signalSource = ServiceLifecycle.trap(signal: signal, handler: { signal in
150111
self.lifecycle.log("intercepted signal: \(signal)")
151112
self.shutdown()
152113
})
@@ -181,20 +142,49 @@ public struct ServiceLifecycle {
181142
}
182143
}
183144

145+
extension ServiceLifecycle {
146+
/// Setup a signal trap.
147+
///
148+
/// - parameters:
149+
/// - signal: The signal to trap.
150+
/// - handler: closure to invoke when the signal is captured.
151+
/// - returns: a `DispatchSourceSignal` for the given trap. The source must be cancled by the caller.
152+
public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global()) -> DispatchSourceSignal {
153+
let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue)
154+
signal(sig.rawValue, SIG_IGN)
155+
signalSource.setEventHandler(handler: {
156+
signalSource.cancel()
157+
handler(sig)
158+
})
159+
signalSource.resume()
160+
return signalSource
161+
}
162+
163+
/// A system signal
164+
public struct Signal {
165+
internal var rawValue: CInt
166+
167+
public static let TERM: Signal = Signal(rawValue: SIGTERM)
168+
public static let INT: Signal = Signal(rawValue: SIGINT)
169+
// for testing
170+
internal static let ALRM: Signal = Signal(rawValue: SIGALRM)
171+
}
172+
}
173+
184174
public extension ServiceLifecycle {
185175
/// Adds a `Task` to a `Tasks` collection.
186176
///
187177
/// - parameters:
188178
/// - tasks: one or more `Tasks`.
189-
func register(_ tasks: Lifecycle.Task ...) {
179+
func register(_ tasks: LifecycleTask ...) {
190180
self.lifecycle.register(tasks)
191181
}
192182

193183
/// Adds a `Task` to a `Tasks` collection.
194184
///
195185
/// - parameters:
196186
/// - tasks: array of `Tasks`.
197-
func register(_ tasks: [Lifecycle.Task]) {
187+
func register(_ tasks: [LifecycleTask]) {
198188
self.lifecycle.register(tasks)
199189
}
200190

@@ -204,7 +194,7 @@ public extension ServiceLifecycle {
204194
/// - label: label of the item, useful for debugging.
205195
/// - start: `Handler` to perform the startup.
206196
/// - shutdown: `Handler` to perform the shutdown.
207-
func register(label: String, start: Lifecycle.Handler, shutdown: Lifecycle.Handler) {
197+
func register(label: String, start: LifecycleHandler, shutdown: LifecycleHandler) {
208198
self.lifecycle.register(label: label, start: start, shutdown: shutdown)
209199
}
210200

@@ -213,7 +203,7 @@ public extension ServiceLifecycle {
213203
/// - parameters:
214204
/// - label: label of the item, useful for debugging.
215205
/// - handler: `Handler` to perform the shutdown.
216-
func registerShutdown(label: String, _ handler: Lifecycle.Handler) {
206+
func registerShutdown(label: String, _ handler: LifecycleHandler) {
217207
self.lifecycle.registerShutdown(label: label, handler)
218208
}
219209

@@ -245,13 +235,13 @@ extension ServiceLifecycle {
245235
/// Defines the `DispatchQueue` on which startup and shutdown callback handlers are run.
246236
public var callbackQueue: DispatchQueue
247237
/// Defines if to install a crash signal trap that prints backtraces.
248-
public var shutdownSignal: [Lifecycle.Signal]?
238+
public var shutdownSignal: [Signal]?
249239
/// Defines what, if any, signals to trap for invoking shutdown.
250240
public var installBacktrace: Bool
251241

252242
public init(logger: Logger = Logger(label: "Lifeycle"),
253243
callbackQueue: DispatchQueue = .global(),
254-
shutdownSignal: [Lifecycle.Signal]? = [.TERM, .INT],
244+
shutdownSignal: [Signal]? = [.TERM, .INT],
255245
installBacktrace: Bool = true) {
256246
self.logger = logger
257247
self.callbackQueue = callbackQueue
@@ -261,18 +251,22 @@ extension ServiceLifecycle {
261251
}
262252
}
263253

254+
struct ShutdownError: Error {
255+
public let errors: [String: Error]
256+
}
257+
264258
// MARK: - ComponentLifecycle
265259

266260
/// `Lifecycle` provides a basic mechanism to cleanly startup and shutdown the application, freeing resources in order before exiting.
267-
public class ComponentLifecycle: Lifecycle.Task {
261+
public class ComponentLifecycle: LifecycleTask {
268262
public let label: String
269263
private let logger: Logger
270264
internal let shutdownGroup = DispatchGroup()
271265

272266
private var state = State.idle
273267
private let stateLock = Lock()
274268

275-
private var tasks = [Lifecycle.Task]()
269+
private var tasks = [LifecycleTask]()
276270
private let tasksLock = Lock()
277271

278272
/// Creates a `ComponentLifecycle` instance.
@@ -369,7 +363,7 @@ public class ComponentLifecycle: Lifecycle.Task {
369363

370364
// MARK: - private
371365

372-
private func _start(on queue: DispatchQueue, tasks: [Lifecycle.Task], callback: @escaping (Error?) -> Void) {
366+
private func _start(on queue: DispatchQueue, tasks: [LifecycleTask], callback: @escaping (Error?) -> Void) {
373367
precondition(tasks.count > 0, "invalid number of tasks, must be > 0")
374368
self.stateLock.withLock {
375369
guard case .idle = self.state else {
@@ -402,7 +396,7 @@ public class ComponentLifecycle: Lifecycle.Task {
402396
}
403397
}
404398

405-
private func startTask(on queue: DispatchQueue, tasks: [Lifecycle.Task], index: Int, callback: @escaping (Int, Error?) -> Void) {
399+
private func startTask(on queue: DispatchQueue, tasks: [LifecycleTask], index: Int, callback: @escaping (Int, Error?) -> Void) {
406400
// async barrier
407401
let start = { (callback) -> Void in queue.async { tasks[index].start(callback) } }
408402
let callback = { (index, error) -> Void in queue.async { callback(index, error) } }
@@ -424,7 +418,7 @@ public class ComponentLifecycle: Lifecycle.Task {
424418
}
425419
}
426420

427-
private func _shutdown(on queue: DispatchQueue, tasks: [Lifecycle.Task], callback: @escaping () -> Void) {
421+
private func _shutdown(on queue: DispatchQueue, tasks: [LifecycleTask], callback: @escaping () -> Void) {
428422
self.stateLock.withLock {
429423
log("shutting down")
430424
self.state = .shuttingDown(queue)
@@ -441,7 +435,7 @@ public class ComponentLifecycle: Lifecycle.Task {
441435
}
442436
}
443437

444-
private func shutdownTask(on queue: DispatchQueue, tasks: [Lifecycle.Task], index: Int, errors: [String: Error]?, callback: @escaping ([String: Error]?) -> Void) {
438+
private func shutdownTask(on queue: DispatchQueue, tasks: [LifecycleTask], index: Int, errors: [String: Error]?, callback: @escaping ([String: Error]?) -> Void) {
445439
// async barrier
446440
let shutdown = { (callback) -> Void in queue.async { tasks[index].shutdown(callback) } }
447441
let callback = { (errors) -> Void in queue.async { callback(errors) } }
@@ -470,17 +464,17 @@ public class ComponentLifecycle: Lifecycle.Task {
470464
private enum State {
471465
case idle
472466
case starting(DispatchQueue)
473-
case started(DispatchQueue, [Lifecycle.Task])
467+
case started(DispatchQueue, [LifecycleTask])
474468
case shuttingDown(DispatchQueue)
475469
case shutdown([String: Error]?)
476470
}
477471
}
478472

479473
public extension ComponentLifecycle {
480-
internal struct Task: Lifecycle.Task {
474+
internal struct Task: LifecycleTask {
481475
let label: String
482-
let start: Lifecycle.Handler
483-
let shutdown: Lifecycle.Handler
476+
let start: LifecycleHandler
477+
let shutdown: LifecycleHandler
484478

485479
func start(_ callback: @escaping (Error?) -> Void) {
486480
self.start.run(callback)
@@ -495,15 +489,15 @@ public extension ComponentLifecycle {
495489
///
496490
/// - parameters:
497491
/// - tasks: one or more `Tasks`.
498-
func register(_ tasks: Lifecycle.Task ...) {
492+
func register(_ tasks: LifecycleTask ...) {
499493
self.register(tasks)
500494
}
501495

502496
/// Adds a `Task` to a `Tasks` collection.
503497
///
504498
/// - parameters:
505499
/// - tasks: array of `Tasks`.
506-
func register(_ tasks: [Lifecycle.Task]) {
500+
func register(_ tasks: [LifecycleTask]) {
507501
self.stateLock.withLock {
508502
guard case .idle = self.state else {
509503
preconditionFailure("invalid state, \(self.state)")
@@ -520,7 +514,7 @@ public extension ComponentLifecycle {
520514
/// - label: label of the item, useful for debugging.
521515
/// - start: `Handler` to perform the startup.
522516
/// - shutdown: `Handler` to perform the shutdown.
523-
func register(label: String, start: Lifecycle.Handler, shutdown: Lifecycle.Handler) {
517+
func register(label: String, start: LifecycleHandler, shutdown: LifecycleHandler) {
524518
self.register(Task(label: label, start: start, shutdown: shutdown))
525519
}
526520

@@ -529,7 +523,7 @@ public extension ComponentLifecycle {
529523
/// - parameters:
530524
/// - label: label of the item, useful for debugging.
531525
/// - handler: `Handler` to perform the shutdown.
532-
func registerShutdown(label: String, _ handler: Lifecycle.Handler) {
526+
func registerShutdown(label: String, _ handler: LifecycleHandler) {
533527
self.register(label: label, start: .none, shutdown: handler)
534528
}
535529

Sources/LifecycleNIOCompat/Bridge.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
import Lifecycle
1616
import NIO
1717

18-
extension Lifecycle.Handler {
18+
extension LifecycleHandler {
1919
/// Asynchronous `Lifecycle.Handler` based on an `EventLoopFuture`.
2020
///
2121
/// - parameters:
2222
/// - future: function returning the underlying `EventLoopFuture`
23-
public static func eventLoopFuture(_ future: @escaping () -> EventLoopFuture<Void>) -> Lifecycle.Handler {
24-
return Lifecycle.Handler { callback in
23+
public static func eventLoopFuture(_ future: @escaping () -> EventLoopFuture<Void>) -> LifecycleHandler {
24+
return LifecycleHandler { callback in
2525
future().whenComplete { result in
2626
switch result {
2727
case .success:

0 commit comments

Comments
 (0)