Open alexcjohnson opened 5 years ago
From the front-end perspective, this adds back-end state to the callback chain that needs to be exposed to the front-end for display purposes. Right now the DAG is reactively drawn based on the information in the dependenciesRequest
object in the redux store, so we would either need that object to be augmented to contain the "which callbacks are in which state" information (and that object needs to be kept up to date) or some equivalent other object needs to live in the store.
It's not back-end state - it's entirely up to the front end whether any given callback should be debugged or not. Two different people could be viewing the same app, one just using it normally and the other asking for debugging of various callbacks.
So I'd suggest adding another object to the redux store for "which callbacks are in which state." This is set by clicking callback circles, and is then fed back into redrawing those circles in a different color as well as used when making a callback request to determine whether to invoke debugging.
🤦♂️ ok yes I read that totally wrong, sorry.
With the current DAG implementation this will be fairly difficult as there's no easy way to add JS click handlers to the individual nodes.
We should investigate moving away from viz.js
towards https://github.com/dagrejs or something like that to make this a real UI component.
@alexcjohnson @nicolaskruchten I'm really excited for this addition, I think it's going to be a game-changer for interactive debugging in DashR.
- For breakpoint, wrap the callback in pdb.runcall, which starts pdb at the beginning of the function, in the server console (eventually perhaps we could pull this to the front end, but that sounds like a much bigger project). Then it's up to the user to run the debugger and allow the function to finish and return.
- For logging we wrap the callback in the appropriate pysnooper call, capture the output, and return it with the output data, and display it in the error console. @rpkyle do both of these modes have equivalents in R?
To emulate breakpoint on the Python side in R, one option is to set a (logical/boolean) flag prior to firing the callback handler again which invokes browser()
. We can't currently use RStudio breakpoints because Dash
is an R6 class, and I don't think we should assume devs are using RStudio at all. browser()
is universally supported.
For logging, I'll have to think a bit more. There's nothing quite like pysnooper
in R, though R does have rudimentary built-in capture tools like sink
, capture.output
and savehistory
:
https://stat.ethz.ch/R-manual/R-devel/library/base/html/sink.html https://stat.ethz.ch/R-manual/R-devel/library/utils/html/capture.output.html https://stat.ethz.ch/R-manual/R-devel/library/utils/html/savehistory.html
I'm not quite sure how we'd replicate the functionality of pysnooper
with these, though.
Now that we have the callback graph in the dev tools UI, let's use that to enable interactive callback debugging!
debug: ('breakpoint'|'logging')
dev_tools_ui: True
(we don't want hackers to be able to hang the back end or dig into back-end code from production apps!), we invoke the specified debugger:breakpoint
, wrap the callback inpdb.runcall
, which startspdb
at the beginning of the function, in the server console (eventually perhaps we could pull this to the front end, but that sounds like a much bigger project). Then it's up to the user to run the debugger and allow the function to finish and return.logging
we wrap the callback in the appropriatepysnooper
call, capture the output, and return it with the output data, and display it in the error console.