Skip to content

Instantly share code, notes, and snippets.

@dpwright
Last active September 30, 2016 18:25
Show Gist options
  • Save dpwright/6588908 to your computer and use it in GitHub Desktop.
Save dpwright/6588908 to your computer and use it in GitHub Desktop.
Watchdog -- Dumb Haskell process monitor
Watchdog
========
Watchdog is a simple utility to spawn and monitor a process, respawning it if it
dies or is killed for whatever reason. This is useful if you have a daemon
process that may encounter an unexpected error, or even just as a quick 'n' easy
upgrade mechanic -- just pop the new executable over the old one and shut the
process down!
There are a million of these, but I needed something quick 'n' dirty to
distribute with another program I was writing in Haskell, so I knocked this
together to go with it.
It's built on top of `System.Process`, naturally. We also want
`System.Environment` and `Control.Monad`:
> import System.Process
> import System.Environment
> import Control.Monad
The program takes the command to run as its argument(s). You can pass this as a
single, quoted argument, or just by passing arguments as parameters to the
program -- but beware of shell expansion!
> getTarget :: IO String
> getTarget = liftM unwords getArgs
We make use of `System.Process.runInteractiveCommand` in order to spawn the
process. This mitigates issues on Windows where the command window appears for
spawned processes. We then drop all the standard streams and wait for the
process to end.
> monitor :: String -> IO ()
> monitor cmd = forever $ runInteractiveCommand cmd >>= handleOutput
> where handleOutput (_, _, _, ps) = waitForProcess ps
In case the user doesn't pass any arguments, display a usage banner:
> help :: IO ()
> help = do
> progName <- getProgName
> putStrLn $ "Usage: " ++ progName ++ " cmd [arguments]"
Finally, it's just a case of putting these pieces together!
> main :: IO ()
> main = getTarget >>= handle
> where handle cmd = if null cmd then help else monitor cmd
The end <3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment