Chapter 10. Immutant Daemons
10.1. Introduction
Daemons are long-running services sharing the lifecycle of your application. Their chief benefit is as a highly available "singleton" service in a cluster of Immutants.
10.2. Starting a Daemon
The primary abstraction is the Daemon protocol, which prescribes
two methods: start and stop. Daemon instances are passed to the
immutant.daemons/create function along with a name. A JMX MBean
is then created and started asynchronously. The stop function is
automatically invoked when your application is undeployed.
A convenience function, immutant.daemons/daemonize, may be used to encapsulate the creation of a Daemon from two functions. It takes three parameters:
name- a name for referencing as a JMX MBeanstart- a start function to be invoked asynchronouslystop- a stop function that will be automatically invoked when your app is undeployed, providing a hook to cleanly teardown resources used by the daemon
In addition, the following options are supported:
| Option | Default | Description |
|---|---|---|
| :singleton | true | Singleton daemons will only execute on one node in a cluster. If false, the daemon will run on every node. |
The :singleton option only applies when deployed to a
cluster. Immutant provides automatic failover for singleton daemons:
should it crash, the daemon will be automatically started on another
node chosen at random, resulting in a robust, highly-available
service.
10.3. Examples
The following contrived examples show a simple mechanism for controlling a daemon via a shared atom.
First, using the Daemon protocol directly:
(ns example.init (:require [immutant.daemons :as daemon])) ;; Controls the state of our daemon (def done (atom false)) ;; An implementation of Daemon (defrecord Service [] daemon/Daemon (start [_] (reset! done false) (loop [i 0] (Thread/sleep 1000) (when-not @done (println i) (recur (inc i))))) (stop [_] (reset! done true))) ;; Register the daemon (daemon/create "mydaemon" (Service.) :singleton true)
And alternatively, passing two functions:
(ns example.init (:require [immutant.daemons :as daemon]) ;; Controls the state of our daemon (def done (atom false)) ;; Our daemon's start function (defn start [] (reset! done false) (loop [i 0] (Thread/sleep 1000) (when-not @done (do-something) (recur (inc i))))) ;; Our daemon's stop function (defn stop [] (reset! done true)) ;; Register the daemon (daemon/daemonize "mydaemon" start stop :singleton false)