State-dependent event processing with state updates

Viewed 339

I want to use FRP (i.e., reactive banana 0.6.0.0) for my project (a GDB/MI front-end). But I have troubles declaring the event network.

There are commands from the GUI and there are stop events from GDB. Both need to be handled and handling them depends on the state of the system.

My current approach looks like this (I think this is the minimum required complexity to show the problem):

data Command = CommandA | CommandB
data Stopped = ReasonA  | ReasonB
data State = State {stateExec :: Exec, stateFoo :: Int}
data StateExec = Running | Stopped

create_network :: NetworkDescription t (Command -> IO ())
create_network = do
    (eCommand, fCommand) <- newEvent
    (eStopped, fStopped) <- newEvent
    (eStateUpdate, fStateUpdate) <- newEvent

    gdb <- liftIO $ gdb_init fStopped

    let
      eState = accumE initialState eStateUpdate
      bState = stepper initialState eState

    reactimate $ (handleCommand gdb fStateUpdate <$> bState) <@> eCommand
    reactimate $ (handleStopped gdb fStateUpdate <$> bState) <@> eStopped

    return fCommand

handleCommand and handelStopped react on commands and stop events depending on the current state. Possible reactions are calling (synchronous) GDB I/O functions and firing state update events. For example:

handleCommand :: GDB -> ((State -> State) -> IO ()) -> State -> Command -> IO ()
handleCommand gdb fStateUpdate state CommandA = case stateExec state of
   Running -> do
     gdb_interrupt gdb
     fStateUpdate f
 where f state' = state' {stateFoo = 23}

The problem is, when f gets evaluated by accumE, state' sometimes is different from state.

I am not 100% sure why this can happen as I don't fully understand the semantics of time and simultaneity and the order of "reactimation" in reactive banana. But I guess that state update functions fired by handleStopped might get evaluated before f thus changing the state.

Anyway, this event network leads to inconsistent state because the assumptions of f on the "current" state are sometimes wrong.

I have been trying to solve this problem for over a week now and I just cannot figure it out. Any help is much appreciated.

2 Answers
Related