Shiny: can input values change _during_ reactive flush?

I can't seem to find concrete documentation on this, so I figured I'd ask (before reading through Shiny's implementation code) ... does Shiny buffer session input changes during reactive flushes? Asked another way, can a session's input value change during a reactive flush? The scenario I'm imagining can be described with the following simplified app components and timeline below:

y <- reactiveVal(NULL)

o1 <- observe({
  y(someFunction(input$x))  ## this is a simplification of a much larger process
})

o2 <- observe({
  isolate(input$x) # used for something else in this observer
  someOtherFunction(y())
})
  1. User interacts with UI element x, setting that value to "1".
  2. Message is received server-side, setting input$x and invalidating o1.
  3. o1 runs during the reactive flush, y is set, o2 is invalidated.
  4. User interacts with UI element x, setting that value to "2"; note that this is client-side, and thus asynchronous from the server-side reactive flushing that's happening.
  5. o2 runs during the reactive flush.

The principal question ... can input$x change values between steps 4 and 5 (e.g. if the socket received the result of step 4 before step 5 started running)? Or is o2's isolate()-ed access to input$x guaranteed to return the same value that o1 saw to during the same reactive flush?

My instinct says that input$x will be set to the new value after the current reactive flush has finished, but that might be false. If input$x can change during a reactive flush, then it'd suggest o1 should run twice during the flush cycle (which implies the potential to run an infinite number of times), which seems faulty and thus unlikely to be the case.

Ultimately, I want to know if o1 will always run before o2 in a reactive flush cycle, and if input$x cannot change during that flush, that'll indeed be the case. If input$x can change, then setting priority values on the observers will be needed to guarantee the o1 --> o2 sequencing.

Can anyone here (ideally someone who works on Shiny) help clarify exactly when during the event loop input values can change?

Cheers and thanks!

While I couldn't find explicit documentation of this within the Shiny docs, I did find this in the promises package docs, which I believe answers my question.

# pseudocode for the reactive flush cycle: ## my comment, not in the original quote
while (TRUE) {
  # Do nothing until a browser sends some data
  input <- receiveInputFromBrowser()
  # Use the received data to update reactive inputs
 session$updateInput(input)
 # Execute all invalidated outputs/observers
 flushReact()
 # After ALL outputs execute, send the results back
 flushOutputs()
}

Only one of the four steps—receiving, updating, reacting, and sending—can be executing a time. (Remember, R is single threaded.) In particular, it’s not possible for inputs to be updated while outputs/observers are running. This is important in order to avoid race conditions that would be all but impossible to defend against.

Hope this helps any searchers in the future!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.