Description
There are (3) main bits to this....
- better support for invariants and pre/post conditions
- pre/post processing filter chains
- dynamic upgrade support
Items (1, 2) are motivated by this kind of code:
-- | Start a counter server
startCounter :: Int -> Process ProcessId
startCounter startCount =
let server = defaultProcess {
dispatchers = [
handleCallIf (state (\count -> count > 10)) -- invariant
(\_ (_ :: Increment) ->
noReply_ (TerminateOther "Count > 10"))
, handleCall handleIncrement
, handleCall (\count (_ :: Fetch) -> reply count count)
, handleCast (\_ Fetch -> continue 0)
]
} :: ProcessDefinition State
in spawnLocal $ start startCount init' server >> return ()
where init' :: InitHandler Int Int
init' count = return $ InitOk count Infinity
Quite what this 'pre/post' condition API will look like will hopefully emerge soon...
Item (3) is not a /hot code upgrade/ as it will only work with what's in the current running image, but it does provide a way to change the process definition on the fly, which is quite useful. This would, for example, allow you to dynamically assign tasks to workers in a pool, or allow you to turn on and off support for certain application level protocols. It's also quite simple to implement, as the upgrades branch demonstrates. We send a Closure (Process TerminateReason)
to the server (bundled in a message) and an automatically registered handler returns ProcessUpgrade fun
and that 'fun' gets evaluated and becomes the main loop. The code that uses this mechanisms calls become newState
and the upgradeHandler
in newState
gets called with oldDefinition -> oldState
.