willdonnelly / dyre

A Dynamic Reconfiguration Library for Haskell Programs

This URL has Read+Write access

Joe Edmonds (author)
Sat Oct 24 08:49:03 -0700 2009
willdonnelly (committer)
Sat Oct 24 13:55:15 -0700 2009
commit  5a188d2bf3ec2b12cf6b09fb4a2a102fb50272d6
tree    6e7003fd2ed315613846653abdd283e4a25bde11
parent  0c64a14d091563406df9716149cf3bef500a5791
dyre /
name age message
directory Config/ Sat Oct 24 13:55:15 -0700 2009 Put code in code block so it gets formatted pro... [Joe Edmonds]
file LICENSE Fri Jul 17 21:30:44 -0700 2009 Cleaned up code a little bit. [willdonnelly]
file README.mkd Sat Sep 12 08:06:56 -0700 2009 Updated documentation. [willdonnelly]
file Setup.hs Thu Jul 23 13:23:23 -0700 2009 Made 'Setup.hs' look nicer. [willdonnelly]
directory Tests/ Sat Sep 12 14:50:14 -0700 2009 Applied HLint suggestions. [willdonnelly]
file dyre.cabal Sat Oct 24 13:55:15 -0700 2009 Put code in code block so it gets formatted pro... [Joe Edmonds]
README.mkd

Dyre - A Dynamic Reconfiguration Library for Haskell

Dyre implements a basic interface for dynamically recompiling Haskell programs with new configurations. The inspiration for all this is, of course, Xmonad's reconfiguration functionality. It is similar in usage to the HConf library which was written for the Yi editor.

Basic Usage

The main interface to the Dyre library consists of three items: a datatype for configuration data, a set of default values, and a function which makes that data into an entry-point function.

A complete, working example can be seen here:

-- DyreExample.hs --
module DyreExample ( dyreExample ) where

import qualified Config.Dyre as Dyre

confError cfgMessage error = "Error:" ++ error ++ "\n" ++ cfgMessage

realMain message = do
    putStrLn "Entered Main Function"
    putStrLn message

dyreExample = Dyre.wrapMain Dyre.defaultParams
    { Dyre.projectName  = "dyreExample"
    , Dyre.showError    = confError
    , Dyre.realMain     = realMain
    }

This code defines a simple library which will display a message on stdout. It uses Dyre to provide configuration of what exactly the message is. The default configuration could look something like this:

-- Main.hs --
import DyreExample
main = dyreExample "This is the default configuration"

While a user's custom configuration would be more like this:

-- dyreExample.hs --
import DyreExample
main = dyreExample "This is a custom configuration"

This example can be run without installing. Simply run Main.hs[^1] with the argument '--dyre-debug', to tell it to search for a configuration file in the current directory. If the custom configuration exists, it will be compiled and executed, or the default message will be displayed if there is no custom configuration.

The Dyre.wrapMain function is how Dyre is meant to be invoked. It is passed a set of parameters which configure how it operates. Most parameters have some good defaults defined in Dyre.defaultParams, except for the three defined in the above code. For a program to successfully run, those three parameters must be overridden.

The Dyre.projectName element is used to search for a custom configuration, the Dyre.showError element is called with compile errors to store the information in the program configuration, and Dyre.realMain is the function which is ultimately the main program entry point.

For the other parameters Dyre uses, consult the Config.Dyre.Params module documentation.

[^1] You can compile it with ghc --make, or simply use runhaskell Main.hs.

Restarting and Persistent State

Restarting is handled by the Config.Dyre.Relaunch module. To simply restart, discarding all state information, use the relaunchMaster function.

If the state needs to be preserved, there are two pairs of functions available. When your program starts, you will want to use ether the restoreTextState or the restoreBinaryState function. Both of these take a default state which is returned when there is no persisted state to use.

Then to restart and persist the state, use the function relaunchWithTextState or relaunchWithBinaryState corresponding to your chosen restore function. The state will be persisted and your program restarted for you.