Skip to content
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

R Session does not start with r_session wait=FALSE #90

Closed
colearendt opened this issue Dec 4, 2018 · 5 comments
Closed

R Session does not start with r_session wait=FALSE #90

colearendt opened this issue Dec 4, 2018 · 5 comments

Comments

@colearendt
Copy link

On RStudio Server Pro (Ubuntu), it looks like wait = FALSE causes the R session to never start / become available (even after waiting a while). Furthermore, it fools callr's understanding of session state, so that it looks like it is available.

library(callr)
rs <- callr::r_session$new(wait = TRUE)
rs
#> R SESSION, alive, idle, pid 5943.
rs$get_state()
#> [1] "idle"
rs$poll_process(100)
#> [1] "timeout"

rs$run(function() 1 + 2)
#> [1] 3

rs2 <- callr::r_session$new(wait = FALSE)
rs2
#> R SESSION, alive, starting, pid 5949.
rs2$get_state()
#> [1] "starting"
rs2$poll_process(100)
#> [1] "timeout"

Sys.sleep(10)

rs2
#> R SESSION, alive, starting, pid 5949.
rs2$get_state()
#> [1] "starting"
rs2$poll_process(100)
#> [1] "ready"

rs2$run(function() 1 + 2)
#> Error in rs_call(self, private, func, args): R session not ready yet

rs$close()
#> NULL
rs2$close()
#> NULL
Session info
devtools::session_info()
#> Session info -------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.4.4 (2018-03-15)
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  tz       Etc/UTC                     
#>  date     2018-12-04
#> Packages -----------------------------------------------------------------
#>  package    * version    date       source                              
#>  assertthat   0.2.0      2017-04-11 RSPM (R 3.4.3)                      
#>  backports    1.1.2      2017-12-13 RSPM (R 3.4.3)                      
#>  base       * 3.4.4      2018-03-16 local                               
#>  base64enc    0.1-3      2015-07-28 RSPM (R 3.4.3)                      
#>  callr      * 3.0.0      2018-08-24 RSPM (R 3.4.4)                      
#>  compiler     3.4.4      2018-03-16 local                               
#>  crayon       1.3.4      2017-09-16 CRAN (R 3.4.0)                      
#>  datasets   * 3.4.4      2018-03-16 local                               
#>  debugme      1.1.0.9000 2018-02-20 Github (gaborcsardi/debugme@f4a116a)
#>  devtools     1.13.4     2017-11-09 CRAN (R 3.4.0)                      
#>  digest       0.6.18     2018-10-10 cran (@0.6.18)                      
#>  evaluate     0.12       2018-10-09 RSPM (R 3.4.4)                      
#>  formatR      1.5        2017-04-25 RSPM (R 3.4.3)                      
#>  graphics   * 3.4.4      2018-03-16 local                               
#>  grDevices  * 3.4.4      2018-03-16 local                               
#>  htmltools    0.3.6      2017-04-28 RSPM (R 3.4.0)                      
#>  knitr        1.20       2018-02-20 RSPM (R 3.4.4)                      
#>  magrittr     1.5        2014-11-22 RSPM (R 3.4.3)                      
#>  memoise      1.1.0      2017-04-21 CRAN (R 3.4.0)                      
#>  methods    * 3.4.4      2018-03-16 local                               
#>  processx     3.2.0      2018-08-16 RSPM (R 3.4.4)                      
#>  ps           1.2.1      2018-11-06 RSPM (R 3.4.4)                      
#>  R6           2.3.0      2018-10-04 cran (@2.3.0)                       
#>  Rcpp         1.0.0      2018-11-07 cran (@1.0.0)                       
#>  rmarkdown    1.10       2018-06-11 cran (@1.10)                        
#>  rprojroot    1.3-2      2018-01-03 RSPM (R 3.4.3)                      
#>  stats      * 3.4.4      2018-03-16 local                               
#>  stringi      1.2.4      2018-07-20 RSPM (R 3.4.4)                      
#>  stringr      1.3.1      2018-05-10 CRAN (R 3.4.3)                      
#>  tools        3.4.4      2018-03-16 local                               
#>  utils      * 3.4.4      2018-03-16 local                               
#>  withr        2.1.2      2018-03-15 RSPM (R 3.4.4)                      
#>  yaml         2.2.0      2018-07-25 cran (@2.2.0)
@colearendt colearendt changed the title Issue with r_session wait=FALSE R Session does not start with r_session wait=FALSE Dec 4, 2018
@gaborcsardi
Copy link
Member

gaborcsardi commented Dec 4, 2018

You need to make $read(), after the poll returns. I.e.:

rs2 <- callr::r_session$new(wait = FALSE)
rs2$poll_process(1000)
rs2$read()
rs2$run(function() 1+1)

@colearendt
Copy link
Author

Ahh interesting! So even if you don't poll, it seems you need to call read before the session is usable? Is that expected behavior?

rs2 <- callr::r_session$new(wait = FALSE)
rs2$run(function() 1 + 2)
#> Error in rs_call(self, private, func, args): R session not ready yet
rs2$read()
#> NULL
rs2$run(function() 2 + 2)
#> Error in rs_call(self, private, func, args): R session not ready yet
Sys.sleep(10)
rs2$run(function() 1 + 1)
#> Error in rs_call(self, private, func, args): R session not ready yet
rs2$read()
#> $code
#> [1] 201
#> 
#> $message
#> [1] "ready to go"
rs2$run(function() 1 + 3)
#> [1] 4

rs2$close()
#> NULL

@colearendt
Copy link
Author

colearendt commented Dec 5, 2018

It seems this is also the case for rs2$call. It will block the R session (even once the task is completed) until rs2$read is called.

I think this makes the r_session less ideal for intermittent / asynchronous background processes. It would be nice for the stateful background R session to have a "queue" of things to execute that I could throw things to whenever I like.

I suspect there is a feature request in here somewhere, but would love your thoughts on what it might be 😄

@gaborcsardi
Copy link
Member

gaborcsardi commented Dec 5, 2018

You are right, it does not have a queue. It can only run one thing at a time. The idea is that callr is only the basic infrastructure, and the queue or process pool would be implemented on top of it.

E.g. https://github.com/r-lib/async/tree/feature/event-loop has a worker pool, but this only works on Unix currently. The benefit of this is that it can mix other kinds of async computation an IO together. E.g. this runs 1) a timer, 2) HTTP, 3) a generic external process, 4) a callr-like fresh R process, and 5) a function call on the worker pool, all in parallel:

 afun <- async(function() {
    when_all(
      delay = delay(1/1000)$
        then(function() 1),
      http = http_get("https://eu.httpbin.org/status/418")$
        then(function(x) x$status_code),
      process = run_process("pwd")$
        then(function(x) str_trim(x$stdout)),
      r_process = run_r_process(function() 2)$
        then(function(x) x$result),
      call = call_function(function() 3)$
        then(function(x) x$result)
    )
  })

  res <- synchronise(afun())

  expect_equal(
    res,
    list(delay = 1,
         http = 418,
         process = getwd(),
         r_process = 2,
         call = 3)
  )

https://github.com/r-lib/async/blob/e358f8aa9e63f883efe326e41614f5474509aa7a/tests/testthat/test-call-function.R#L107-L131

Considering that there is no timeline for releasing that package, though, it might be worth thinking about adding a simple worker pool on top of r_session.

@gaborcsardi
Copy link
Member

I'll close this. We might have a small worker pool before the fate of the async package is sorted out, but considering that its API would need some time to mature, it is better to put it in another package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants