-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: for debugging, would be very useful to know which reactive caused invalidation #1846
Comments
That's really interesting. Are you thinking a function which would return some kind of string or list based description, that you could do your own println-debugging with? |
Yes, I'm not sure or really care about the exact syntax, but something like this
Sometimes I see people's code where a large reactive is called multiple times (instead of once) and this sort of thing could really help speed up finding out the cause |
Note to self. Not which reactive, but the call stack that caused a dependency on the reactive. We care about the call site of taking the dependency, not the dependency itself. This should be collected only behind a flag because of the performance hit (collecting and formatting a stack on every reactive read). |
Call stack that is causing the invalidation may be good too, actually. In cases where an input is being updated due to a message being received by the client, not so helpful. But for stacks where observers set reactive values, it would be useful. |
That's exactly how i arrived here via Rstudio's community then StackOverflow...it literally this usage that today would have saved me so much time :) |
++ |
I've been experimenting with ways to do this without having to change Shiny. My first idea was based on @jcheng5's notes above - print the current call stack in the relevant upstream reactives, or in the observer It kinda worked, but the stack trace lacked key info like inputs being set, or labels for the invalidated contexts. Maybe these are possible to get but I hit a dead end. Second idea was to run a profiler and collect/parse the call stacks. This also worked in some cases, but wasn't reliable because of the sampling. Last idea was to just parse it out of the reactive log. Similar to what @yonicd did, build the dependency graph in R, then follow the invalidated dependencies to figure out what caused invalidation. I used https://github.com/glin/reactlog options(shiny.reactlog = TRUE)
foo <- reactive({
reactlog::traceInvalidation()
x1()
}) This package also includes a way to list reactive dependencies in a tree view, since multiple dependencies can change, not just the one that caused invalidation. And initial attempts at hacking some of @daattali and Joe's ideas from #1532 into the reactive log visualizer - filtering on graph nodes and jumping to the next flush cycle. But even with filtering, I think I still prefer to just look at a stack trace when working on larger apps. Demos if you want to see how this looks: |
I know this isn't a sexy or fun feature, but I wanted to ping here to re-grab attention. I think this may not be as low priority as many of my other requests because this could immensely help debugging in large apps and save hours for many developers. I'm sure there are lots of apps out there that get invalidated way more than they need to, causing bad experiences for the users, but the developers simply could not figure out why and left it. I work with many clients and see this a lot :) |
I'm not sure if this is possible, but if it is it could help tremendously when debugging larger apps. Sometimes a render or reactive code block gets called and you have no idea why--what reactive exactly caused it to execute. There isn't an easy way to do that kind of debugging in non trivial apps right now. The closest thing is the react graph log, which is awesome, but gets impossible to use for larger apps
The text was updated successfully, but these errors were encountered: