On Oct 24, 2012, at 2:13 PM, Richard D. Morey wrote: > This question involves Rook, but I think the answer will be general enough > that it pays to post here. At any rate, I don't know enough to know whether > this is a Rook only issue or a general R issue. > > Here's what I'd like to do (and indeed, have code that should do this): > > 1. Start R, Rook > 2. Start an analysis via a HTTP request to Rook. This analysis uses .Call() > to some compiled C code, if that matters. The C code calls a callback > function to update a variable with its progress. > 3. While the analysis is happening, use Rook to obtain current status with an > HTTP request >
You can't. R doesn't support threading so it's simply not possible to have an asynchronous eval. The R HTTP server works by simply enqueuing an eval to run while R is idle, it can't do that if R is busy. (Note that the HTTP server was *only* designed for the internal help). What you can do is have your C code start another thread that reports the progress when asked e.g. on a socket, but that thread is not allowed to call any R API so you want that progress to be entirely in your C code. Note that if your C code is robust enough, it can call R_CheckUserInterrupt() to allow external events to happen, but a) your C code must in that case be prepared for early termination (clean up memory etc.) and b) I don't remember if the httpd is allowed to run during interrupt check on all platforms - you may want to check that first. Cheers, Simon > The problem is that once the analysis starts, Rook does not respond to > requests. All of the status requests to Rook pile up, and then are answered > when the analysis (step 2) is done. Here is some example code to demonstrate > what the issue: > > ########## > > library(Rook) > s <- Rhttpd$new() > s$add( > name="pingpong", > app=Rook::URLMap$new( > '/ping' = function(env){ > req <- Rook::Request$new(env) > res <- Rook::Response$new() > res$write('This is ping.') > Sys.sleep(20) > res$finish() > }, > '/pong' = function(env){ > req <- Rook::Request$new(env) > res <- Rook::Response$new() > res$write("This is pong.") > res$finish() > }, > '/?' = function(env){ > req <- Rook::Request$new(env) > res <- Rook::Response$new() > res$redirect(req$to_url('/pong')) > res$finish() > } > ) > ) > > s$start(quiet=TRUE) > s$browse('pingpong') > > ############################# > > If you request /ping, R runs Sys.sleep() for 20 seconds. This is where my > .Call() statement would be. While the .Call() (Sys.sleep()) function is doing > its thing, I need to get Rook to respond on /pong (which would simply respond > with the progress), but if you run this code, request /ping, then immediately > request /pong, you'll see that the /pong request will not be answered until > the Sys.sleep() is done. > > Of course, for a progress report to be useful, the requests have to be > answered immediately. Is this a Rook issue, or an R issue? Or am I asking > something unreasonable? > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel