Skip to content

GenProcess improvements #62

Open
Open
@hyperthunk

Description

@hyperthunk

There are (3) main bits to this....

  1. better support for invariants and pre/post conditions
  2. pre/post processing filter chains
  3. 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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions