From a76f7fb5402ced55f3cff4fb4aa64e39eef12e98 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 08:24:25 +0100 Subject: [PATCH 1/9] Updated target dependency example Updated the dependency to use .product as instructed by SPM when trying to follow the instructions. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65e5f15..09206d0 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ To add a dependency on the package, declare it in your `Package.swift`: and to your application target, add `Lifecycle` to your dependencies: ```swift -.target(name: "MyApplication", dependencies: ["Lifecycle"]), +.target(name: "MyApplication", dependencies: [.product(name: "Lifecycle", package: "swift-service-lifecycle")]), ``` ### Defining the lifecycle From 64c7fe4ab45ecef58a2d4cb12cd2742c0db05edc Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 09:10:48 +0100 Subject: [PATCH 2/9] Added USR1/USR2 signals --- Sources/Lifecycle/Lifecycle.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index dc5b723..1ee5287 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -194,6 +194,9 @@ extension ServiceLifecycle { public static let TERM = Signal(rawValue: SIGTERM) public static let INT = Signal(rawValue: SIGINT) + public static let USR1 = Signal(rawValue: SIGUSR1) + public static let USR2 = Signal(rawValue: SIGUSR2) + // for testing internal static let ALRM = Signal(rawValue: SIGALRM) From 222475c30fe7f5e0b2c03053f4022eec05b20c93 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 09:25:44 +0100 Subject: [PATCH 3/9] Optionally allow to let signal handler run multiple times, useful for USR signals --- Sources/Lifecycle/Lifecycle.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index 1ee5287..a3b7a51 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -177,11 +177,13 @@ extension ServiceLifecycle { /// - signal: The signal to trap. /// - handler: closure to invoke when the signal is captured. /// - returns: a `DispatchSourceSignal` for the given trap. The source must be cancelled by the caller. - public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global()) -> DispatchSourceSignal { + public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global(), cancelAfterTrap: Bool = true) -> DispatchSourceSignal { let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue) signal(sig.rawValue, SIG_IGN) signalSource.setEventHandler(handler: { - signalSource.cancel() + if (cancelAfterTrap) { + signalSource.cancel() + } handler(sig) }) signalSource.resume() From a33fdc88abb789b8737cedc2f47ec15a07a39122 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 09:42:13 +0100 Subject: [PATCH 4/9] Added HUP signal support. Motivation: Adding support for capturing HUP too in addition to USR1/USR2. Modifications: Added HUP signal, added descriptive strings for new signals. Result: HUP and USR signals available. --- Sources/Lifecycle/Lifecycle.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index a3b7a51..825f64c 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -198,7 +198,8 @@ extension ServiceLifecycle { public static let INT = Signal(rawValue: SIGINT) public static let USR1 = Signal(rawValue: SIGUSR1) public static let USR2 = Signal(rawValue: SIGUSR2) - + public static let HUP = Signal(rawValue: SIGHUP) + // for testing internal static let ALRM = Signal(rawValue: SIGALRM) @@ -208,7 +209,11 @@ extension ServiceLifecycle { case Signal.TERM: result += "TERM, " case Signal.INT: result += "INT, " case Signal.ALRM: result += "ALRM, " - default: () // ok to ignore + case Signal.USR1: result += "USR1, " + case Signal.USR2: result += "USR2, " + case Signal.HUP: result += "HUP, " + + default: () // ok to ignore } result += "rawValue: \(self.rawValue))" return result From 8d379dc91912822d930bf0e2afbbdffd480db446 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 21:44:47 +0100 Subject: [PATCH 5/9] Trying to fix soundness failures, adding documentation. Motivation: Trying to adhere to code standards. Modifications: Removing tabs replacing with whitespace. Result: Adhering to soundness.sh, adding documentation. --- Sources/Lifecycle/Lifecycle.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index 825f64c..994ac2a 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -158,7 +158,7 @@ public struct ServiceLifecycle { let signalSource = ServiceLifecycle.trap(signal: signal, handler: { signal in self.log("intercepted signal: \(signal)") self.shutdown() - }) + }, cancelAfterTrap: true) self.underlying.shutdownGroup.notify(queue: .global()) { signalSource.cancel() } @@ -177,7 +177,7 @@ extension ServiceLifecycle { /// - signal: The signal to trap. /// - handler: closure to invoke when the signal is captured. /// - returns: a `DispatchSourceSignal` for the given trap. The source must be cancelled by the caller. - public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global(), cancelAfterTrap: Bool = true) -> DispatchSourceSignal { + public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global(), cancelAfterTrap: Bool = false) -> DispatchSourceSignal { let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue) signal(sig.rawValue, SIG_IGN) signalSource.setEventHandler(handler: { From 921c30c56f18cdea7022f96eb118511d0e6dd169 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 21:49:37 +0100 Subject: [PATCH 6/9] Remove tab. --- Sources/Lifecycle/Lifecycle.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index 994ac2a..219fc6e 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -176,14 +176,16 @@ extension ServiceLifecycle { /// - parameters: /// - signal: The signal to trap. /// - handler: closure to invoke when the signal is captured. + /// - on: DispatchQueue to run the signal handler on (default global dispatch queue) + /// - cancelAfterTrap: Defaults to false, which means the signal handler can be run multiple times. If true, the DispatchSignalSource will be cancelled after being trapped once. /// - returns: a `DispatchSourceSignal` for the given trap. The source must be cancelled by the caller. public static func trap(signal sig: Signal, handler: @escaping (Signal) -> Void, on queue: DispatchQueue = .global(), cancelAfterTrap: Bool = false) -> DispatchSourceSignal { let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue) signal(sig.rawValue, SIG_IGN) signalSource.setEventHandler(handler: { - if (cancelAfterTrap) { - signalSource.cancel() - } + if (cancelAfterTrap) { + signalSource.cancel() + } handler(sig) }) signalSource.resume() @@ -196,10 +198,10 @@ extension ServiceLifecycle { public static let TERM = Signal(rawValue: SIGTERM) public static let INT = Signal(rawValue: SIGINT) - public static let USR1 = Signal(rawValue: SIGUSR1) + public static let USR1 = Signal(rawValue: SIGUSR1) public static let USR2 = Signal(rawValue: SIGUSR2) public static let HUP = Signal(rawValue: SIGHUP) - + // for testing internal static let ALRM = Signal(rawValue: SIGALRM) From 7fc68b37147124aa198642ce2db9303b60f032b4 Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 22:44:09 +0100 Subject: [PATCH 7/9] Whitespace fix. --- Sources/Lifecycle/Lifecycle.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index 219fc6e..2db8efd 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -214,8 +214,8 @@ extension ServiceLifecycle { case Signal.USR1: result += "USR1, " case Signal.USR2: result += "USR2, " case Signal.HUP: result += "HUP, " - - default: () // ok to ignore + default: () // ok to ignore + } result += "rawValue: \(self.rawValue))" return result From 1843fb993dbc1df32740a728162c1afc0702658d Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Fri, 12 Mar 2021 23:27:29 +0100 Subject: [PATCH 8/9] Fix final whitespace (I hope). --- Sources/Lifecycle/Lifecycle.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index 2db8efd..d67e4ec 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -183,9 +183,9 @@ extension ServiceLifecycle { let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue) signal(sig.rawValue, SIG_IGN) signalSource.setEventHandler(handler: { - if (cancelAfterTrap) { - signalSource.cancel() - } + if (cancelAfterTrap) { + signalSource.cancel() + } handler(sig) }) signalSource.resume() @@ -215,7 +215,6 @@ extension ServiceLifecycle { case Signal.USR2: result += "USR2, " case Signal.HUP: result += "HUP, " default: () // ok to ignore - } result += "rawValue: \(self.rawValue))" return result From 265fb15d1b8fa6e259fd05fa12308262a926454f Mon Sep 17 00:00:00 2001 From: Joakim Hassila Date: Sat, 13 Mar 2021 05:21:07 +0100 Subject: [PATCH 9/9] Remove superfluous paranthesis in if statement --- Sources/Lifecycle/Lifecycle.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Lifecycle/Lifecycle.swift b/Sources/Lifecycle/Lifecycle.swift index d67e4ec..6979aba 100644 --- a/Sources/Lifecycle/Lifecycle.swift +++ b/Sources/Lifecycle/Lifecycle.swift @@ -183,7 +183,7 @@ extension ServiceLifecycle { let signalSource = DispatchSource.makeSignalSource(signal: sig.rawValue, queue: queue) signal(sig.rawValue, SIG_IGN) signalSource.setEventHandler(handler: { - if (cancelAfterTrap) { + if cancelAfterTrap { signalSource.cancel() } handler(sig)