R tcltk responsive gui during calculation - r

Hello dear stack overflow community.
i'm currently working on an R project for statistical calculations that involves a gui and also time consuming heuristics. in the gui shall be an button to start and stop the calculation and a textfield that reports the best error so far.
so i'm stuck with the question how to keep the gui responsive during the calculation.
some example code
require("tcltk")
result<-tclVar("")
start<-function(){
active<<-TRUE
tkconfigure(button,text="stop",command=stop)
dostuff()
}
stop<-function(){
active<<-FALSE
tkconfigure(button,text="start",command=start)
}
dostuff<-function(){#this would be the optimization function
while(active){
tclvalue(result)<-#do some stuff
}
}
toplevel<-tktoplevel()
button<-tkbutton(toplevel,text="start",command=start)
entry<-tkentry(toplevel,textvariable=result)
tkpack(button)
tkpack(entry)
in the do stuff function some multithreading stuff seems to be necessary. its a requirement to work on windows and linux. i'm hoping for ideas how to archive this. thanks in advance

I think the easiest way is to start an R script as background process using system or system2 with the wait=FALSE parameter so that the long running calculation is processed in the background.
If you want to update the UI to show intermediate results or progress the R script must write the current state into an "exchange" file that can be used to update the UI.
To update the UI you have to check for the new state periodically e. g. by using the after command of Tcl/Tk, see:
http://www.tcl.tk/man/tcl/TclCmd/after.htm
For an example of starting an R script as background process see here:
http://stackoverflow.com/questions/14208976/r-run-source-in-background
Note that R is single threaded and updating the Tk-UI must be done from the same thread (process) that created the UI since the main event loop is running here.
Also take care that you shouldn't allow the user to make conflicting changes via the UI while the background task is running (e. g. starting another background task - except you want to support this).
Canceling the background process via the UI ("cancel button") can be done best by using another "signal file" that is checked by the background process periodically.

Related

Shiny app is stalled when executing a big calculation

I'm new to shiny , couldn't get my answer anywhere tho.
I have a heavy code aggregating tables in R. I wanted to move it to the Web app and I chose Shiny as my original code is written in R so I thought it saves me lots of time.
When I run the code by
ObserveEvent(actionbutton$do,{mybigcalculation(input_tables)})
my code is running but at the time of executing my code, it's not possible to do other stuff like exploring tables in the other tabs.The rendering part works but he web app functionalities is completely frozen at the time the process is running.
Any help would be highly appreciated ? if this doesn't work I have to move to typical web app development by having backend ( e.g plumber ) and frontend (e.g React) in separate servers.
Thank you
After a long investigation, I think I found the answer. I'm writing it down here as you might face this issue quite often developing your web app by Shiny. Always there are some big processes you wanna do and wanna make sure your async works great.
There are libraries (future & promises packages) that Cheng explains them here. it says, they can take the calculations in the background and make them come back with the result while the shiny app is doing its normal job. It didn't work for me and I still had my web app stalled. But what I saw, they did increase mybigcalculation speed dramatically. Also it took it to the background makes it invisible in the console.
I found my answer in a package called Shiny.worker library.
Now my app is working fine while my expensive code is running in the background. I made my ideal execution(fast and async) by wrapping future package inside of a shiny worker library.
So it looks something like this:
load.lib <- c("promises","future","shiny.worker")
install.lib <- load.lib[!load.lib %in% installed.packages()]
for(lib in install.lib) install.packages(lib,dependencies=TRUE)
sapply(load.lib,library,character=TRUE)
plan(multisession)
initiate the worker by:
worker <- shiny.worker::initialize_worker()
then:
wrapper <- function(args) {
future::future(my_heavy_calculations(args$r))
}
reactive_arguments <- reactive({
input$start
list(r = rnorm(1))
})
resultPromise <- worker$run_job("job1", wrapper, args_reactive = reactive_arguments)
resultPromise()$result # contains the result of the calculations
resultPromise()$resolved # contains flag that informs whether the job has finished or not
I'm looking forward for any idea and suggestions that can makes the answer better.

R/Shiny: View full stack/execution log

I'm debugging a Shiny web app, and would like to see the entire control flow/execution path over the course of rendering and updating the generated website.
Is there a way to capture/print/dump-to-file every line of code that is executed in the process of rendering/updating a Shiny app? It would also be good (maybe better?) to see every line of R code parsed by the running R interpreter instance; I'm not concerned about length of this output, and would prefer to get things as verbosely as possible.
I have looked into the stack tracing Shiny functions but these seem to be intended for error catching/handling/reporting. The app is not generating errors/warnings, just setting some variables to NULL at some point when they shouldn't be, so I'm not sure if this is the right approach. These stack tracing functions also seem to be more localized, designed to operate within a given reactive variable/function/render rather than following the control/execution flow across differing reactives/rendering functions in an app.
This app is a large, company-internal app so I cannot give a MRE/MWE.
I finally found the profvis package that does more-or-less exactly what I want by taking a snapshot of the execution stack at a fixed time interval (default 10ms). I'm still working on using this tool to debug, but I believe this will get me there and would also be useful to others debugging Shiny apps that need more than browser() and/or reactlog.
Specifically, I have been doing:
#install.packages("profvis")
library(profvis)
exec_log <- profvis(runApp("myShinyApp"))
...interact with the myShinyApp web page enough to trigger the bug, then interrupt execution...
print(exec_log)

R Shiny Server - set a loading animation on application startup

I've used shinyapps.io in the past and it provides a loading animation (spinner) while the application starts up. This is useful because I load 200MB of .RData-files into the memory (once on startup, not for every server()). This takes up to 40 seconds (in future, I will transition towards storing the data in a database, but for now this is what I got).
For other applications, I've used the docker image rocker/shiny and wanted to fully transition to a Docker-based approach and put all my shiny applications on one server and move away from shinyapps.io. However, the one issue I have with this application is that it does not display a loading animation while it starts so the user is left with a grey screen for a good 30-40 seconds while the data is loaded in the background.
As for the code, I load all data and then I source ui.R and server.R before running shiny::shinyApp(ui = ui, server = server).
Does any of you know a way to specify a loading animation on startup of the application (I haven't found anything in the server configuration itself but I could have overlooked something)? Or have you found a nice workaround to achieve the desired result?
So what I ended up doing was to follow this workaround suggested here: http://www.mazsoft.com/blog/post/2018/01/01/show-progress-bar-when-pre-loading-data-in-shiny-app
The idea is that we initialize all data variables with NULL. Then there is a readData() function outside of server and ui where we load all the data into the global variables and at the beginning of the server function block we check if one of our data variables is.null() which would lead us to call the readData() function.
It is an okay solution for my problem as it's a nice workaround, yet I wasn't able to figure out how to actually display a loading animation on startup, just while loading the data. I hope this helps people with a similar same problem.

Coded UI execution is extremely slow than usual?

I have coded UI project with five UIMaps.One of the UIMap is very large and it covers several features of the testing application.suddenly the coded UI playback become so slow. I separate some features from the large UIMap into separate UIMaps. But still some of the test methods running very slower than usual.Is there any solutions to fix this issue?
You can use the below settings in your TestInitialize part and check whether this solves your purpose.As now we don’t need to add the annoying Sleep statements whenever a UI Control is busy and not ready to receive input.
By default, the engine checks the UI Thread (foreground thread) to determine if a control is ready.
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
By implementing this you can reduce the execution time.
I can not comment yet so here is an answer.
I had the same problem. see Coded ui Test fails at random times on server
waitforcontrolready was a solution next to PropertyExpressionOperator.Contains to search for a variable title. But also check the controlID of your control in your UIMap. It can change depending which windows are open on screen.
I remove them all unless I am 100% sure it stays the same.
I have figured it out after a search in the net, the class name of the main window is changed because of the latest releases. I have check the latest main window name and add it in the UIMap constructor as instructed in the following link Mathew Aniyan's Blog

Using a pyqt widget from a linearly running console application

My scenario here is the following: I am using a pyqt widget to display a solid color fullscreen on a second display and observe this display with a camera that is continuously capturing images. I do some processing with the images and this is the data I am interested in. This works great when used interactively with ipython and matplotlib using the qt4agg backend like so
% ipython -pylab
# ... import PatternDisplay, starting camera
pd = PatternDisplay(); pd.show(); pd.showColor(r=255,g=255,b=255)
imshow(cam.current_image)
I need a similar behavior now in a console script though: it should display the PatternDisplay widget, capture an image, than change the color on the PatternDisplay and take a new image and so on.
The problem is now that the PatternDisplay is never updated/redrawn in my script, likely because PyQt never gets a chance to run it's event queue. I had no luck trying to move the linear worker part of my script into a QThread because I cannot communicate with the PatternDisplay Widget from another Thread any longer. I tried to replicate the implementation of ipython/matplotlib, but I didn't fully understand it, it is quite complicated - it avoids running the QApplication main loop via monkey patching and somehow moves QT into it's own thread. It then checks periodically using a QTimer if a new command was entered by the user.
Isn't there an easy way to achieve what I want to do? I am gladly providing more information if needed. Thanks for any help!
What you need is easier than IPython's job - IPython makes the Qt application and the command line interactive at the same time.
I think the way to do it in Qt is to use a timer which fires at regular intervals, and connect the signal to the 'slot' representing your function that gets the new image and puts it in the widget. So you're pulling it in from the event loop, rather than trying to push it.
I've not used Qt much, so I can't give specifics, but the more I think about it, the more I think that's the right way to do it.
I solved the same problem (i.e. interactive ipython console in terminal, and GUI thread running independently) in the following way with ipython 0.10 (code here)
1. Construct QApplication object, but don't enter its event loop explicitly
2. Run the embedded IPython instance
3. Run the UI code you need by instantiating your window and calling show() on it (like here with the yade.qt.Controller(), which I aliased to F12. (I did not find a way how to ask the embedded shell to run a command at the start of the session, as if the user had typed it)
(You can also show() your window first, then run the embedded ipython. It will provide event loop for Qt.)
(BTW I also tried running Qt4 from a background thread (using both python threads module, and Qt4.QThreads), but it refuses to run in such way stubbornly. Don't bother going that way.)
The disadvantage is that UI will be blocked while ipython is busy. I hope to finding something better for 0.11, which should have much better threading facilities (I asked on ipython-users about how to unblock the UI).
HTH, v.

Resources