In what way is the execution order of reactiva-banana's execute not guaranteed?
Asked Answered
H

0

6

The documentation for the execute function in Reactive.Banana.Frameworks says that "there is no guarantee about the order in which the actions are executed."

I'm not sure which ordering is meant here. As the event only fires one action at once, there isn't much of an order to guarantee here, so the most likely scenario I can imagine is this:

a :: MomentIO (Event t)
a = ...

b :: MomentIO (Event t)
b = ...

makeEvent :: MomentIO (Event (MomentIO (Event t))
makeEvent = fromAddHandler $ ... -- Some AddHandler that first fires a
                                 -- and later fires b

network :: MomentIO ()
network = do
  ...
  newEvents <- makeEvent
  ts <- execute newEvents >>= switchE
  ...

The non-guarantee I can imagine here is that the execution order of a and b is switched, thus b gets executed first. If we assume that a and b both modify the behavior of some widget (using liftIO) and then register their corresponding event handler (unregistering the previously registered one), switching the execution order of a and b would be fatal as it would leave the widget in a state where it doesn't fire the handlers it supposed to fire. As I don't see for which use cases execute is still useful if my scenario is correct, I suppose the documentation actually means something else.

Can someone please clarify what the documentation is trying to say here?

Henrie answered 12/2, 2017 at 18:31 Comment(6)
The docs say: "You can even do IO actions here, which is useful if you want to register additional event handlers dynamically. However, there is no guarantee about the order in which the actions are executed." (emphasis mine) - I think (pure speculation) it is referring to the order of "IO actions" i.e. liftIO ... :: MomentIO X - not to FRP "primitives" provided by the library (which, if they do IO, presumably they do so in a way that the library knows about and can handle properly)Disdain
@Disdain That's what I tried to describe. FRP structures created in the MomentIO monad usually are connected to some IO resources (e.g. widgets), which are usually set up in the same monad using liftIO. But if the ordering of those IO actions isn't guaranteed I can't be sure that my FRP structures actually mirror the currently rendered UI.Henrie
My understanding is that if you create an FRP 'resource' (like a widget), even it it 'lives' inside IO, the event network will have knowledge of it and will be able to manage it appropriately. OTOH, if you read a file or connect to a database with liftIO, the event network will have no knowledge of those things, and would have no way to enforce 'ordering' between them (e.g. an IO action may be 'guarded' by an input which never occurs). (Of course my understanding could be wrong! I've never run into this particular issue with FRP so I'm not speaking from experience)Disdain
And I always thought that this is said about a situation when you have two events fired simultaneously. In this case there is no guarantee that they will be executed in order they were registered.Ora
Heinrich here. As @Ora pointed out, the remark in the documentation was meant to highlight that when execute is used with different events that occur simultaneously, then the relative order between the IO actions in different execute is undefined. Within a single execute, IO occurs in sequence, as you would expect (and there is no way I could change that, actually). I should add an example to the documentation. Could you add an issue on github?Tournament
@HeinrichApfelmus I was just going over over my questions without an accepted answer. Maybe you would like to post your answer as such, so I can mark it as accepted?Henrie

© 2022 - 2024 — McMap. All rights reserved.