Daemons in Haskell made fun and easy
Here's AddOne, a simple daemon that waits for a number and responds with the incremented number.
import Data.Default ( def )
import System.Environment ( getArgs )
import System.Daemon
addOne :: Int -> IO Int
addOne n = return (n + 1)
main :: IO ()
main = do
ensureDaemonRunning "addOne" def addOne
[n] <- getArgs
res <- runClient "localhost" 5000 ((read n) :: Int)
print (res :: Maybe Int)
Running it, we see:
% addone 22
Daemon started on port 5000
Just 23
% addone 41
Just 42
The two important functions above are ensureDaemonRunning
, which
checks if a daemon named addOne
is already running, and starts it if
not, and runClient
which connects to the daemon running on
localhost:5000
, passes it a number, and waits for the response.
-
You can use the
runDetached
fromSystem.Posix.Daemon
to turn your program into a daemon for Unix-like systems. You'd want to do this for practically every program that's meant to run as a server. -
You can use the functions from
Control.Pipe.C3
,Socket
, andSerialize
to communicate with running Haskell program. At the simplest, you could query the program for its status, or instruct it to shutdown cleanly. A more complex use would be adding a full REPL into a running Haskell process (thinkerl -remsh
). -
You can use the helpers from
System.Daemon
to trivially do the above. Check out the following tutorials and examples for details.
-
Memo - in which we write an in-memory key-value store,
-
- a task queue using the streaming interface of
daemons
.
- a task queue using the streaming interface of
This package is on Hackage. To install it, run:
cabal update
cabal install daemons
-
Control.Pipe.C3
provides simple RPC-like wrappers for pipes. -
Control.Pipe.Serialize
provides pipes to serialize and deserialize streams of strictByteString
s using cereal. -
Control.Pipe.Socket
provides functions to setup strictByteString
pipes around sockets. -
System.Daemon
provides a high-level interface to starting daemonized programs that are controlled through sockets. -
System.Posix.Daemon
provides a low-level interface to starting, and controlling detached jobs.
-
pipes
The Pipes Tutorial -
C3
Wikipedia