reflex
reflex copied to clipboard
What actions prevent `performEvent` from emitting an event in the same frame as its input?
The documentation for performEvent
has a note that most performable actions can't occur during event propagation, resulting in output events ocurring later than input events, but I was hoping for some clarification on exactly what that means in practice. My assumption from this was that probably anything using liftIO
would qualify, but I encountered a bug in my own code recently which has me questioning this.
Basically I had a Dynamic
whose event had been created with newTriggerEvent
, so that I could change its value within calls to performEvent
, and had a sequence of performEvents
, some of which sampled that dynamic, and some of which wrote to it. I assumed that this would be safe to do, but it appeared as if reads which occured after writes weren't observing the change. This would make sense to me if it all happened within the same frame, but not otherwise. I was able to fix the bug by simply using delay
in between, but was curious what can be relied on here, or if my intution about how frames work is just entirely wrong.
Additionally, I'm also wondering if whether writing to two separate events both created by newTriggerEvent
within the same frame can be counted on to output the events simultaneously, if I do something like
(ev1, send1) <- newTriggerEvent
(ev2, send2) <- newTriggerEvent
performEvent $ ffor someEv \_ -> liftIO
send1 someVal
send2 someOtherVal
I think what I'm wanting fundamentally is something like newTunnel :: m (Event t a, Event t a -> m ())
, with the guarantee that there's no delay between events entering the tunnel and events exiting. I can write this using newTriggerEvent
and performEvent
, but just don't know if has the guarantees I want. As I said, my assumption initially was that it wasn't, until I encountered this bug, and now think maybe it is possible.