JBoss.orgCommunity Documentation

Chapter 11. Immutant Daemons

11.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.

11.2. Starting a Daemon

The primary abstraction is the immutant.daemons/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 the daemon 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 MBean
  • start - a start function to be invoked asynchronously
  • stop - 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:

OptionDefaultDescription
:singletontrueSingleton 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.

11.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)
Immutant 1.1.3