rstudio / promises

A promise library for R
https://rstudio.github.io/promises
Other
201 stars 19 forks source link

Error: ‘inherits(future, "Future")’ is not TRUE #107

Open sebsilas opened 4 months ago

sebsilas commented 4 months ago

Describe the bug

When I try to load a promise in the context of starting up a Shiny app, I get the following error:

Error: ‘inherits(future, "Future")’ is not TRUE

This doesn't happen consistently.

The traceback (see below) is interesting. It suggests my promise is of cluster type, even though I have used plan(multisession). If I explicitly set the plan when calling future_promise, I still get the same behaviour.

Reproduce example


library(shiny)
library(promises)

ui <- fluidPage(

    titlePanel("Promise fail"),

)

server <- function(input, output, session) {

  on_start(session)

}

on_start <- function(session) {

  future::plan(future::multisession)

  res <- promises::future_promise({
    Sys.sleep(5)
    "test_res"
  }, seed = NULL) %...>% (function(result) {
    print(result)
  })

}

# Run the application
shinyApp(ui = ui, server = server)

Expected behavior

I expect the promise not to fail.

Traceback

13: stop(cond)
12: stopf("%s is not TRUE", sQuote(call), call. = FALSE, domain = NA)
11: stop_if_not(inherits(future, "Future"))
10: post_mortem_cluster_failure(ex, when = "checking resolved from", 
        node = node, future = future)
9: resolved.ClusterFuture(x, timeout = 0)
8: future::resolved(x, timeout = 0)
7: withCallingHandlers(expr, error = function(e) {
       promiseDomain$onError(e)
   })
6: doTryCatch(return(expr), name, parentenv, handler)
5: tryCatchOne(expr, names, parentenv, handlers[[1L]])
4: tryCatchList(expr, classes, parentenv, handlers)
3: base::tryCatch(withCallingHandlers(expr, error = function(e) {
       promiseDomain$onError(e)
   }), ..., finally = finally)
2: tryCatch({
       future::resolved(x, timeout = 0)
   }, FutureError = function(e) {
       reject(e)
       TRUE
   })
1: (function () 
   {
       is_resolved <- tryCatch({
           future::resolved(x, timeout = 0)
       }, FutureError = function(e) {
           reject(e)
           TRUE
       })
       if (is_resolved) {
           tryCatch({
               result <- future::value(x, signal = TRUE)
               resolve(result)
           }, FutureError = function(e) {
               reject(e)
               TRUE
           }, error = function(e) {
               reject(e)
           })
       }
       else {
    ...

Session information

> sessionInfo()

R version 4.3.0 (2023-04-21)
Platform: x86_64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.6.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Berlin
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] promises_1.2.1 shiny_1.8.0    devtools_2.4.5 usethis_2.2.3 

loaded via a namespace (and not attached):
 [1] jsonlite_1.8.8    miniUI_0.1.1.1    compiler_4.3.0    Rcpp_1.0.12      
 [5] stringr_1.5.1     parallel_4.3.0    jquerylib_0.1.4   later_1.3.2      
 [9] globals_0.16.3    fastmap_1.1.1     mime_0.12         R6_2.5.1         
[13] htmlwidgets_1.6.4 future_1.33.1     profvis_0.3.8     bslib_0.7.0      
[17] rlang_1.1.3       cachem_1.0.8      stringi_1.8.3     httpuv_1.6.14    
[21] sass_0.4.9        fs_1.6.3          pkgload_1.3.4     memoise_2.0.1    
[25] cli_3.6.2         withr_3.0.0       magrittr_2.0.3    digest_0.6.35    
[29] rstudioapi_0.15.0 xtable_1.8-4      remotes_2.5.0     lifecycle_1.0.4  
[33] vctrs_0.6.5       glue_1.7.0        listenv_0.9.1     urlchecker_1.0.1 
[37] codetools_0.2-19  sessioninfo_1.2.2 pkgbuild_1.4.4    parallelly_1.37.1
[41] purrr_1.0.2       tools_4.3.0       ellipsis_0.3.2    htmltools_0.5.8.1
…
> future::futureSessionInfo()

*** Package versions
future 1.33.1, parallelly 1.37.1, parallel 4.3.0, globals 0.16.3, listenv 0.9.1

*** Allocations
availableCores():
system 
    16 
availableWorkers():
$system
 [1] "localhost" "localhost" "localhost" "localhost" "localhost" "localhost" "localhost"
 [8] "localhost" "localhost" "localhost" "localhost" "localhost" "localhost" "localhost"
[15] "localhost" "localhost"

*** Settings
- future.plan=<not set>
- future.fork.multithreading.enable=<not set>
- future.globals.maxSize=<not set>
- future.globals.onReference=<not set>
- future.resolve.recursive=<not set>
- future.rng.onMisuse=<not set>
- future.wait.timeout=<not set>
- future.wait.interval=<not set>
- future.wait.alpha=<not set>
- future.startup.script=<not set>

*** Backends
Number of workers: 16
List of future strategies:
1. multisession:
   - args: function (..., workers = availableCores(), lazy = FALSE, rscript_libs = .libPaths(), envir = parent.frame())
   - tweaked: FALSE
   - call: future::plan(future::multisession)

*** Basic tests
Main R session details:
    pid     r sysname release
1 85671 4.3.0  Darwin  22.6.0
                                                                                                 version
1 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
  nodename machine   login    user effective_user
1  host001  x86_64 user001 user002        user002
Worker R session details:
   worker   pid     r sysname release
1       1 86370 4.3.0  Darwin  22.6.0
2       2 86367 4.3.0  Darwin  22.6.0
3       3 86369 4.3.0  Darwin  22.6.0
4       4 86372 4.3.0  Darwin  22.6.0
5       5 86376 4.3.0  Darwin  22.6.0
6       6 86366 4.3.0  Darwin  22.6.0
7       7 86374 4.3.0  Darwin  22.6.0
8       8 86373 4.3.0  Darwin  22.6.0
9       9 86371 4.3.0  Darwin  22.6.0
10     10 86368 4.3.0  Darwin  22.6.0
11     11 86378 4.3.0  Darwin  22.6.0
12     12 86379 4.3.0  Darwin  22.6.0
13     13 86380 4.3.0  Darwin  22.6.0
14     14 86377 4.3.0  Darwin  22.6.0
15     15 86375 4.3.0  Darwin  22.6.0
16     16 86365 4.3.0  Darwin  22.6.0
                                                                                                  version
1  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
2  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
3  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
4  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
5  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
6  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
7  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
8  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
9  Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
10 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
11 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
12 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
13 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
14 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
15 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
16 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64
   nodename machine   login    user effective_user
1   host001  x86_64 user001 user002        user002
2   host001  x86_64 user001 user002        user002
3   host001  x86_64 user001 user002        user002
4   host001  x86_64 user001 user002        user002
5   host001  x86_64 user001 user002        user002
6   host001  x86_64 user001 user002        user002
7   host001  x86_64 user001 user002        user002
8   host001  x86_64 user001 user002        user002
9   host001  x86_64 user001 user002        user002
10  host001  x86_64 user001 user002        user002
11  host001  x86_64 user001 user002        user002
12  host001  x86_64 user001 user002        user002
13  host001  x86_64 user001 user002        user002
14  host001  x86_64 user001 user002        user002
15  host001  x86_64 user001 user002        user002
16  host001  x86_64 user001 user002        user002
Number of unique worker PIDs: 16 (as expected)
…
sebsilas commented 4 months ago

Here is a video of the behaviour:

https://github.com/rstudio/promises/assets/39628712/da4c4728-7736-43e2-80df-4e249d96a184

I believe this might only be happening when I launch the window from RStudio. Thus, a workaround is to simply turn that behaviour off using launch.browser = FALSE.

Edit: No, I can actually reproduce this just clicking "Run App" in RStudio. The behaviour is so inconsistent.

trafficonese commented 1 month ago

I also see that error in some shiny-apps, when hitting F5 (reload) sometimes..

Fehler: ‘inherits(future, "Future")’ is not TRUE
Fehler: invoke_wrapped: throwing std::runtime_error

I have multiple ExtendedTask in some apps, using this structure:

data <- reactiveValues(cur = NULL, old = NULL)

get_data_async <- ExtendedTask$new(function(url, time) {
  future_promise(seed=TRUE, {
    library("jsonify"); library("httr");
    get_data(url, time)
  })
})

## Invoke Extended Task
observe({
  ## .. some reactives and input checks
  get_data_async$invoke("someip", "tiimeconfig")
})

## Listen to Status
observe({
  txt <- req(get_data_async$status())
  if (txt == "running") {
  } else if (txt == "error") {
    warning("\nOffset-Future got rejected:\n");
    print(get_data_async$result())
    offsetdata$cur <- NULL
  } else if (txt == "success") {
    res <- get_data_async$result()
    if (is.null(res)) {
      data$cur <- NULL
      return(NULL)
    }
    data$cur <- res
  }
})

## Do something with the result
output$text <- renderPrint({
  data$cur
})
trafficonese commented 1 month ago

I think putting future::plan(future::multisession) inside the global.R works.

I was using some delayed start of the multisession..

multisessionrv <- reactiveVal(NULL)
futuresusp <- observe(suspended = TRUE, {
  library(future)
  library(promises)
  plan(multisession)
  multisessionrv(TRUE) 
})
thekangaroofactory commented 2 weeks ago

I also randomly get this error Will try the global.R approach :)