Skip to content

Commit

Permalink
Merge pull request #297 from DeLaGuardo/main
Browse files Browse the repository at this point in the history
Collect exceptions caught during shutdown
  • Loading branch information
Magisus authored Dec 17, 2021
2 parents 0cd1ed8 + 9b157a7 commit 8780276
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 18 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
## 3.2.0-SNAPSHOT

This is a minor feature release

* Backward compatible changes to the signature of `puppetlabs.trapperkeeper.internal/shutdown!` function. Returns collection of exceptions caught during execution of shutdown sequence instead of nil.
* Extend `stop` method of `puppetlabs.trapperkeeper.app/TrapperkeeperApp` protocol with an argument `throw?` to handle cases where exceptions in shutdown sequence should be rethrown.
* Change default behavior of `puppetlabs.trapperkeeper.testutils.bootstrap` helper macroses to throw exception when shutdown finished abruptly.

## 3.1.1

This is a maintenance release

* Updates to current clj-parent

## 3.1.0

This is a minor feature release

* [PDB-4636](https://github.com/puppetlabs/trapperkeeper/pull/287) - support custom exit status/messages

## 3.0.0

This is a maintenance release

* Updates to current clj-parent to clean up project.clj and update dependencies
* Tests changes for readability and compatibility with Java11

## 2.0.1

This is a maintenance release
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject puppetlabs/trapperkeeper "3.1.2-SNAPSHOT"
(defproject puppetlabs/trapperkeeper "3.2.0-SNAPSHOT"
:description "A framework for configuring, composing, and running Clojure services."

:license {:name "Apache License, Version 2.0"
Expand Down
4 changes: 2 additions & 2 deletions src/puppetlabs/trapperkeeper/app.clj
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@
"occurred, return the input parameter."))
(init [this] "Initialize the services")
(start [this] "Start the services")
(stop [this] "Stop the services")
(restart [this] "Stop and restart the services"))
(stop [this] [this throw?] "Stop the services")
(restart [this] "Stop and restart the services"))
38 changes: 28 additions & 10 deletions src/puppetlabs/trapperkeeper/internal.clj
Original file line number Diff line number Diff line change
Expand Up @@ -448,24 +448,36 @@
(shutdown-on-error [this svc-id f] (shutdown-on-error* shutdown-reason-promise app-context svc-id f))
(shutdown-on-error [this svc-id f on-error] (shutdown-on-error* shutdown-reason-promise app-context svc-id f on-error))))

(schema/defn ^:always-validate shutdown!
(schema/defn ^:always-validate shutdown! :- [Throwable]
"Perform shutdown calling the `stop` lifecycle function on each service,
in reverse order (to account for dependency relationships)."
in reverse order (to account for dependency relationships).
Returns collection of exceptions thrown during shutdown sequence execution."
[app-context :- (schema/atom a/TrapperkeeperAppContext)]
(log/info (i18n/trs "Beginning shutdown sequence"))
(let [{:keys [ordered-services shutdown-channel lifecycle-worker]} @app-context
shutdown-fn (fn [] (doseq [[service-id s] (reverse ordered-services)]
(try
(run-lifecycle-fn! app-context s/stop "stop" service-id s)
(catch Exception e
(log/error e (i18n/trs "Encountered error during shutdown sequence"))))))]
errors-chan (async/promise-chan)
shutdown-fn (fn [] (let [results
(doall
(keep
(fn [[service-id s]]
(try
(run-lifecycle-fn! app-context s/stop "stop" service-id s)
nil
(catch Exception e
(log/error e (i18n/trs "Encountered error during shutdown sequence"))
e)))
(reverse ordered-services)))]
(async/put! errors-chan results)))]
(log/trace (i18n/trs "Putting shutdown message on shutdown channel."))
(async/>!! shutdown-channel {:type :shutdown
:task-function shutdown-fn})
;; wait for the channel to send us the return value so we know it's done
(log/trace (i18n/trs "Waiting for response to shutdown message from lifecycle worker."))
(if (not (nil? (async/<!! lifecycle-worker)))
(log/info (i18n/trs "Finished shutdown sequence"))
(do
(log/info (i18n/trs "Finished shutdown sequence"))
;; deliver errors from stopped services if any
(async/<!! errors-chan))
;; else, the read from the channel returned a nil because it was closed,
;; indicating that there was already a shutdown in progress, and thus the
;; redundant shutdown request was ignored
Expand Down Expand Up @@ -606,8 +618,14 @@
(inc-restart-counter! this)
this)
(a/stop [this]
(shutdown! app-context)
this)
(a/stop this false))
(a/stop [this throw?]
(let [errors (shutdown! app-context)]
(if (and throw? (seq errors))
(let [msg (i18n/trs "Error during app shutdown!")]
(log/error msg)
(throw (ex-info msg {:errors errors})))
this)))
(a/restart [this]
(try
(run-lifecycle-fns app-context s/stop "stop" (reverse ordered-services))
Expand Down
3 changes: 2 additions & 1 deletion test/puppetlabs/trapperkeeper/shutdown_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
app (bootstrap-services-with-empty-config [test-service broken-service])]
(is (false? @shutdown-called?))
(logging/with-test-logging
(internal/shutdown! (app-context app))
(let [errors (internal/shutdown! (app-context app))]
(is (= '("dangit") (map #(.getMessage ^Throwable %) errors))))
(is (logged? #"Encountered error during shutdown sequence" :error)))
(is (true? @shutdown-called?)))))

Expand Down
8 changes: 4 additions & 4 deletions test/puppetlabs/trapperkeeper/testutils/bootstrap.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
(try
~@body
(finally
(tk-app/stop ~app))))))
(tk-app/stop ~app true))))))

(defn bootstrap-services-with-cli-data
[services cli-data]
Expand All @@ -37,7 +37,7 @@
(try
~@body
(finally
(tk-app/stop ~app))))))
(tk-app/stop ~app true))))))

(defn bootstrap-services-with-cli-args
[services cli-args]
Expand All @@ -51,7 +51,7 @@
(try
~@body
(finally
(tk-app/stop ~app))))))
(tk-app/stop ~app true))))))

(defn bootstrap-services-with-empty-config
[services]
Expand All @@ -64,7 +64,7 @@
(try
~@body
(finally
(tk-app/stop ~app))))))
(tk-app/stop ~app true))))))

(defn bootstrap-with-empty-config
([]
Expand Down

0 comments on commit 8780276

Please sign in to comment.