rstudio / promises

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

Recommended way to debug promises #55

Closed Tazovsky closed 4 years ago

Tazovsky commented 4 years ago

Since there is no way to easily retrieve value of fulfilled promise what is the recommended way to debug shiny promises?

Let's take for example following code:

library(shiny)
library(shinydashboard)
library(glue)
library(promises)

header <- dashboardHeader(
  title = "Example Shiny app"
)

body <- dashboardBody(
  fluidRow(
    column(width = 9,
           box(width = NULL, solidHeader = TRUE,
               shiny::dateInput("date", "Date", value = "2018-05-28")
           )
    )
  )
)

ui <- dashboardPage(
  header,
  dashboardSidebar(disable = TRUE),
  body
)

server <- function(input, output, session) {
  data <- eventReactive(input$date, {
    date <- input$date  # Example: 2018-05-28
    year <- lubridate::year(date)  # Example: "2018"

    url <- glue("http://cran-logs.rstudio.com/{year}/{date}.csv.gz")
    if (!dir.exists("data_cache")) dir.create("data_cache")
    path <- file.path("data_cache", paste0(date, ".csv.gz"))

    future::future({
      if (!file.exists(path)) {
        download.file(url, path)
      }
      read_csv(path, col_types = "Dti---c-ci", progress = FALSE)
    })
  })

  whales <- reactive({
    df <- data() %...>%
      count(ip_id) %...>%
      arrange(desc(n)) %...>%
      head(input$count)

    browser()
    df
  })

  observe({
    df <- whales()

    browser()
  })
}

shinyApp(ui = ui, server = server)

So what do you recommend in debugging scenario where I'd like to check result of data() %...>% count(ip_id)? Usually (in non async app) I'd put browser() and execute data() %...>% count(ip_id), but in this case it returns nothing:

Browse[1]> data() %...>%
+       count(ip_id)
Browse[1]> 

and final output - as discussed here - is not obtainable in easy and recommended way:

Browse[1]> df
<Promise [pending]>
Browse[1]>

I know it is always possible - for debugging needs - to rewrite it to normal %>% pipeline without future, but still case shown in example is very simple pipeline using %...>%. Imagine now production app where reactivity and pipelines are much more complex, they are written using promises and you have to debug them...

jcheng5 commented 4 years ago

(Sorry, I missed this...)

I'd insert a %...T>% { browser() } and look at the value of the . variable.

data() %...T>% { browser() } %...>%
  count(ip_id)
jcheng5 commented 4 years ago

Or just %...T>% str if you just want to know what the value looks like.