    (java.io Closeable)
    [java.util.concurrent.locks ReentrantLock]
    [org.joda.time Period]))
+
+(defn stop-reporters [registries]
+  (letfn [(stop [[registry & registries]]
+            (when registry
+              (try!
+               (stop registries)
+               (finally
+                 ;; Not certain whether :reporter can be nil
+                 (some-> (:reporter registry) jmx-reporter/stop)))))]
+    (stop (vals registries))))
+
+(defn init-puppetdb
+  [context]
+  (with-final [_ metrics/metrics-registries :error stop-reporters
+               cmd-event-ch (async/chan 1000) :error async/close!
+               cmd-event-mult (async/mult cmd-event-ch) :error async/untap-all]
+    (doseq [{:keys [reporter]} (vals metrics/metrics-registries)]
+      (jmx-reporter/start reporter))
+    (assoc context
+           :cmd-event-ch cmd-event-ch
+           :cmd-event-mult cmd-event-mult
+           :url-prefix (atom nil)
+           ;; This coordination is needed until we no longer
+           ;; support jdk < 10.
+           ;; https://bugs.openjdk.java.net/browse/JDK-8176254
+           :stop-status (atom {})
+           :shutdown-request (atom nil))))
 
 (def database-metrics-registry (get-in metrics/metrics-registries [:database :registry]))
 

            [metrics.gauges :refer [gauge-fn]]
            [metrics.timers :refer [time! timer]]
            [metrics.reporters.jmx :as jmx-reporter]
            [murphy :refer [with-final]]
            [overtone.at-at :refer [mk-pool every interspaced stop-and-reset-pool!]]
            [puppetlabs.i18n.core :refer [trs tru]]
            [puppetlabs.kitchensink.core :as kitchensink]

                               get-registered-endpoints
                               (shutdown-requestor request-shutdown this)))

  (stop [this context] (stop-puppetdb context))

  (set-url-prefix [this url-prefix]
                  (let [old-url-prefix (:url-prefix (service-context this))]
