rstudio / shiny

Easy interactive web applications with R
https://shiny.posit.co/
Other
5.35k stars 1.87k forks source link

shiny behaving differently depending on viewer type and webdriver #3233

Closed yonicd closed 3 years ago

yonicd commented 3 years ago

I am running an app that is showing different reactlog behavior depending on the browser/viewer I am using, should the behavior be browser agnostic?

The app repository is here: https://github.com/yonicd/puzzlemath

reactlog jsons: reactlogs.zip

I am running reactlog only until the app in invalidated at startup:

From the logs you can see that shiny is creating duplicates of elements in the window viewer and the windowexternal compared to the paneviewer which is then creating additional reactivity that shouldnt be happening.

here are screenshots of reactlog

System details

Browser Version:

session info ```r ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── setting value version R version 3.6.3 (2020-02-29) os macOS Catalina 10.15.7 system x86_64, darwin15.6.0 ui RStudio language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz America/New_York date 2020-12-23 ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── package * version date lib source askpass 1.1 2019-01-13 [1] CRAN (R 3.6.0) assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) attempt 0.3.1 2020-05-03 [1] CRAN (R 3.6.2) binman 0.1.1 2018-07-18 [1] CRAN (R 3.6.0) bitops 1.0-6 2013-08-17 [1] CRAN (R 3.6.0) caTools 1.18.0 2020-01-17 [1] CRAN (R 3.6.0) cli 2.2.0 2020-11-20 [1] CRAN (R 3.6.2) clipr 0.7.1 2020-10-08 [1] CRAN (R 3.6.2) codetools 0.2-16 2018-12-24 [1] CRAN (R 3.6.3) colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.0) config 0.3 2018-03-27 [1] CRAN (R 3.6.0) crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) curl 4.3 2019-12-02 [1] CRAN (R 3.6.0) deldir 0.2-3 2020-11-09 [1] CRAN (R 3.6.2) desc 1.2.0.9000 2020-09-28 [1] Github (r-lib/desc@c175259) details 0.2.1 2020-01-12 [1] local digest 0.6.27 2020-10-24 [1] CRAN (R 3.6.2) dockerfiler 0.1.3 2019-03-19 [1] CRAN (R 3.6.0) dplyr 1.0.2 2020-08-18 [1] CRAN (R 3.6.2) ellipsis 0.3.1 2020-05-15 [1] CRAN (R 3.6.2) evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0) fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) farver 2.0.3 2020-01-16 [1] CRAN (R 3.6.0) fastmap 1.0.1 2019-10-08 [1] CRAN (R 3.6.0) fs 1.5.0 2020-07-31 [1] CRAN (R 3.6.2) generics 0.0.2 2018-11-29 [1] CRAN (R 3.6.0) ggplot2 3.3.2 2020-06-19 [1] CRAN (R 3.6.2) ggvoronoi 0.8.3 2019-02-19 [1] CRAN (R 3.6.0) glue 1.4.2 2020-08-27 [1] CRAN (R 3.6.2) golem 0.3.0 2020-12-06 [1] local gridExtra 2.3 2017-09-09 [1] CRAN (R 3.6.0) gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.0) htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.2) httpuv 1.5.4 2020-06-06 [1] CRAN (R 3.6.2) httr 1.4.2 2020-07-20 [1] CRAN (R 3.6.2) jsonlite 1.7.2 2020-12-09 [1] CRAN (R 3.6.2) knitr 1.30 2020-09-22 [1] CRAN (R 3.6.2) labeling 0.3 2014-08-23 [1] CRAN (R 3.6.0) later 1.1.0.9000 2020-12-12 [1] Github (r-lib/later@ff8c451) lattice 0.20-38 2018-11-04 [1] CRAN (R 3.6.3) lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.0) magick 2.2 2019-08-26 [1] CRAN (R 3.6.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 3.6.2) mime 0.9 2020-02-04 [1] CRAN (R 3.6.0) munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.0) openssl 1.4.3 2020-09-18 [1] CRAN (R 3.6.2) pagedown 0.9 2020-03-18 [1] CRAN (R 3.6.0) pillar 1.4.7 2020-11-20 [1] CRAN (R 3.6.2) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.0) pkgload 1.1.0 2020-05-29 [1] CRAN (R 3.6.2) png 0.1-7 2013-12-03 [1] CRAN (R 3.6.0) processx 3.4.5 2020-11-30 [1] CRAN (R 3.6.2) promises 1.1.1.9001 2020-11-25 [1] Github (rstudio/promises@bbadb3d) ps 1.5.0 2020-12-05 [1] CRAN (R 3.6.2) purrr 0.3.4 2020-04-17 [1] CRAN (R 3.6.2) puzzlemath * 0.0.3 2020-12-22 [1] local R6 2.5.0 2020-10-28 [1] CRAN (R 3.6.2) raster 3.4-5 2020-11-14 [1] CRAN (R 3.6.2) Rcpp 1.0.5 2020-07-06 [1] CRAN (R 3.6.2) reactlog 1.1.0 2020-09-12 [1] CRAN (R 3.6.2) reactor 0.2.1 2020-12-22 [1] local remotes 2.2.0 2020-07-21 [1] CRAN (R 3.6.2) rgeos 0.5-3 2020-05-08 [1] CRAN (R 3.6.2) rlang 0.4.9 2020-11-26 [1] CRAN (R 3.6.2) rmarkdown 2.5 2020-10-21 [1] CRAN (R 3.6.3) roxygen2 7.1.1 2020-06-27 [1] CRAN (R 3.6.2) rprojroot 2.0.2 2020-11-25 [1] Github (r-lib/rprojroot@5bafca9) rsconnect 0.8.16 2019-12-13 [1] CRAN (R 3.6.2) RSelenium 1.7.7 2020-02-03 [1] CRAN (R 3.6.1) rstudioapi 0.13 2020-11-12 [1] CRAN (R 3.6.2) scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.0) semver 0.2.0 2017-01-06 [1] CRAN (R 3.6.0) sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0) shiny * 1.5.0 2020-06-23 [1] CRAN (R 3.6.2) shinyjs 1.0 2018-01-08 [1] CRAN (R 3.6.0) shinyWidgets 0.5.0 2019-11-18 [1] CRAN (R 3.6.0) sp 1.4-4 2020-10-07 [1] CRAN (R 3.6.2) stringi 1.5.3 2020-09-09 [1] CRAN (R 3.6.2) stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) testthat 3.0.0 2020-10-31 [1] CRAN (R 3.6.2) tibble 3.0.4 2020-10-12 [1] CRAN (R 3.6.2) tidyselect 1.1.0 2020-05-11 [1] CRAN (R 3.6.2) usethis 1.9.0.9000 2020-11-25 [1] Github (r-lib/usethis@2a7ee3b) vctrs 0.3.5 2020-11-17 [1] CRAN (R 3.6.2) viridis 0.5.1 2018-03-29 [1] CRAN (R 3.6.0) viridisLite 0.3.0 2018-02-01 [1] CRAN (R 3.6.0) wdman 0.2.5 2020-01-31 [1] CRAN (R 3.6.0) whereami 0.1.9 2020-09-24 [1] local withr 2.3.0 2020-09-22 [1] CRAN (R 3.6.2) xfun 0.19 2020-10-30 [1] CRAN (R 3.6.2) XML 3.98-1.20 2019-06-06 [1] CRAN (R 3.6.0) xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.2) xtable 1.8-4 2019-04-21 [1] CRAN (R 3.6.0) yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library ```


Example application or steps to reproduce the problem

```R install.packages('reactlog') remotes::install_github('yonicd/puzzlemath@17def58') library(reactlog) library(puzzlemath) library(shiny) reactlog::reactlog_enable() ### Pane Viewer ---- options(shiny.launch.browser = .rs.invokeShinyPaneViewer) shiny::reactlogReset() # the following is akin to running puzzlemath::run_app() shinyApp( ui = puzzlemath:::app_ui, server = puzzlemath:::app_server ) # save to disk cat(jsonlite::serializeJSON(shiny::reactlog()), file = "~/shinytest/puzzlemath_paneviewer.json",sep='\n') ### Window Viewer ---- options(shiny.launch.browser = .rs.invokeShinyWindowViewer) shiny::reactlogReset() shinyApp( ui = puzzlemath:::app_ui, server = puzzlemath:::app_server ) # save to disk cat(jsonlite::serializeJSON(shiny::reactlog()), file = "~/shinytest/puzzlemath_windowviewer.json",sep='\n') options(shiny.launch.browser = .rs.invokeShinyWindowExternal) shiny::reactlogReset() shinyApp( ui = puzzlemath:::app_ui, server = puzzlemath:::app_server ) # save to disk cat(jsonlite::serializeJSON(shiny::reactlog()), file = "~/shinytest/puzzlemath_windowexternal.json",sep='\n') ``` ### Describe the problem in detail
wch commented 3 years ago

It's possible that this is related to #3181. In that case, the reactiveVals weren't actually still around; they just had entries in the reactlog that weren't scoped to the session, so they remained in the "global" part of the reactlog even after a session ended.

Are you sure this is related to the specific browser, or do the extra entries just accumulate when you open/reload the app in more browser windows?

yonicd commented 3 years ago

I am running the app in clean sessions each time.

I initially saw this using {whereami} reactive counter that got hit inconsistently which is basically reflecting the same issue through a different logging scheme.

Here is the output from that attempt: https://gist.github.com/yonicd/024baffb3117d8270b95232f49b334f8

{reactor} is creating independent sessions of webdriver/processx and running unit tests then unlinking the side effects.

You can see the same behavior is happening in that output which is independent of possible reactlog activity.

wch commented 3 years ago

I see the exact same reactlog graph in each of the three cases when I do the following, making sure to restart R between each run:

install.packages('shiny')
install.packages('reactlog')
remotes::install_github('yonicd/puzzlemath@17def58')

### Pane Viewer ---- 
### RESTART R HERE ###
library(reactlog)
library(puzzlemath)
library(shiny)
reactlog::reactlog_enable()
options(shiny.launch.browser = .rs.invokeShinyPaneViewer)
shiny::reactlogReset()
shinyApp(
  ui = puzzlemath:::app_ui, 
  server = puzzlemath:::app_server
)
reactlogShow()

### Window Viewer ---- 
### RESTART R HERE ###
library(reactlog)
library(puzzlemath)
library(shiny)
reactlog::reactlog_enable()
options(shiny.launch.browser = .rs.invokeShinyWindowViewer)
shiny::reactlogReset()
shinyApp(
  ui = puzzlemath:::app_ui, 
  server = puzzlemath:::app_server
)
reactlogShow()

# External browser ----------
### RESTART R HERE ###
library(reactlog)
library(puzzlemath)
library(shiny)
reactlog::reactlog_enable()
options(shiny.launch.browser = .rs.invokeShinyWindowExternal)
shiny::reactlogReset()
shinyApp(
  ui = puzzlemath:::app_ui, 
  server = puzzlemath:::app_server
)
reactlogShow()

image

Session info ``` > sessioninfo::session_info() ─ Session info ───────────────────────────────────────────────────────────────────────────── setting value version R version 4.0.3 (2020-10-10) os Ubuntu 16.04.7 LTS system x86_64, linux-gnu ui RStudio language (EN) collate C.UTF-8 ctype C.UTF-8 tz Etc/UTC date 2020-12-24 ─ Packages ───────────────────────────────────────────────────────────────────────────────── package * version date lib source assertthat 0.2.1 2019-03-21 [1] RSPM (R 4.0.3) attempt 0.3.1 2020-05-03 [1] RSPM (R 4.0.3) cli 2.2.0 2020-11-20 [1] RSPM (R 4.0.3) codetools 0.2-16 2018-12-24 [2] CRAN (R 4.0.3) colorspace 2.0-0 2020-11-11 [1] RSPM (R 4.0.3) config 0.3.1 2020-12-17 [1] RSPM (R 4.0.3) crayon 1.3.4 2017-09-16 [1] RSPM (R 4.0.3) curl 4.3 2019-12-02 [1] RSPM (R 4.0.3) deldir 0.2-3 2020-11-09 [1] RSPM (R 4.0.3) desc 1.2.0 2018-05-01 [1] RSPM (R 4.0.3) digest 0.6.27 2020-10-24 [1] RSPM (R 4.0.3) dockerfiler 0.1.3 2019-03-19 [1] RSPM (R 4.0.3) ellipsis 0.3.1 2020-05-15 [1] RSPM (R 4.0.3) fansi 0.4.1 2020-01-08 [1] RSPM (R 4.0.3) farver 2.0.3 2020-01-16 [1] RSPM (R 4.0.3) fastmap 1.0.1 2019-10-08 [1] RSPM (R 4.0.3) fs 1.5.0 2020-07-31 [1] RSPM (R 4.0.3) ggplot2 3.3.2 2020-06-19 [1] RSPM (R 4.0.3) ggvoronoi 0.8.3 2019-02-19 [1] RSPM (R 4.0.3) glue 1.4.2 2020-08-27 [1] RSPM (R 4.0.3) golem 0.2.1 2020-03-05 [1] RSPM (R 4.0.3) gridExtra 2.3 2017-09-09 [1] RSPM (R 4.0.3) gtable 0.3.0 2019-03-25 [1] RSPM (R 4.0.3) htmltools 0.5.0 2020-06-16 [1] RSPM (R 4.0.3) httpuv 1.5.4 2020-06-06 [1] RSPM (R 4.0.3) jsonlite 1.7.2 2020-12-09 [1] CRAN (R 4.0.3) knitr 1.30 2020-09-22 [1] RSPM (R 4.0.3) labeling 0.4.2 2020-10-20 [1] RSPM (R 4.0.3) later 1.1.0.1 2020-06-05 [1] RSPM (R 4.0.3) lattice 0.20-41 2020-04-02 [2] CRAN (R 4.0.3) lifecycle 0.2.0 2020-03-06 [1] RSPM (R 4.0.3) magick 2.5.2 2020-11-10 [1] RSPM (R 4.0.3) magrittr 2.0.1 2020-11-17 [1] RSPM (R 4.0.3) mime 0.9 2020-02-04 [1] RSPM (R 4.0.3) munsell 0.5.0 2018-06-12 [1] RSPM (R 4.0.3) pillar 1.4.7 2020-11-20 [1] RSPM (R 4.0.3) pkgconfig 2.0.3 2019-09-22 [1] RSPM (R 4.0.3) pkgload 1.1.0 2020-05-29 [1] RSPM (R 4.0.3) promises 1.1.1 2020-06-09 [1] RSPM (R 4.0.3) purrr 0.3.4 2020-04-17 [1] RSPM (R 4.0.3) puzzlemath * 0.0.3 2020-12-24 [1] Github (yonicd/puzzlemath@17def58) R6 2.5.0 2020-10-28 [1] RSPM (R 4.0.3) raster 3.4-5 2020-11-14 [1] RSPM (R 4.0.3) Rcpp 1.0.5 2020-07-06 [1] RSPM (R 4.0.3) reactlog * 1.1.0 2020-09-12 [1] RSPM (R 4.0.3) remotes 2.2.0 2020-07-21 [1] RSPM (R 4.0.3) rgeos 0.5-5 2020-09-07 [1] RSPM (R 4.0.3) rlang 0.4.9 2020-11-26 [1] RSPM (R 4.0.3) roxygen2 7.1.1 2020-06-27 [1] RSPM (R 4.0.3) rprojroot 2.0.2 2020-11-15 [1] RSPM (R 4.0.3) rstudioapi 0.13 2020-11-12 [1] RSPM (R 4.0.3) scales 1.1.1 2020-05-11 [1] RSPM (R 4.0.3) sessioninfo 1.1.1 2018-11-05 [1] RSPM (R 4.0.3) shiny * 1.5.0 2020-06-23 [1] RSPM (R 4.0.3) shinyjs 2.0.0 2020-09-09 [1] RSPM (R 4.0.3) shinyWidgets 0.5.4 2020-10-06 [1] RSPM (R 4.0.3) sp 1.4-4 2020-10-07 [1] RSPM (R 4.0.3) stringi 1.5.3 2020-09-09 [1] RSPM (R 4.0.3) stringr 1.4.0 2019-02-10 [1] RSPM (R 4.0.3) testthat 3.0.1 2020-12-17 [1] RSPM (R 4.0.3) tibble 3.0.4 2020-10-12 [1] RSPM (R 4.0.3) usethis 2.0.0 2020-12-10 [1] RSPM (R 4.0.3) vctrs 0.3.6 2020-12-17 [1] RSPM (R 4.0.3) viridis 0.5.1 2018-03-29 [1] RSPM (R 4.0.3) viridisLite 0.3.0 2018-02-01 [1] RSPM (R 4.0.3) whereami 0.1.9 2019-11-07 [1] RSPM (R 4.0.3) withr 2.3.0 2020-09-22 [1] RSPM (R 4.0.3) xfun 0.19 2020-10-30 [1] RSPM (R 4.0.3) xml2 1.3.2 2020-04-23 [1] RSPM (R 4.0.3) xtable 1.8-4 2019-04-21 [1] RSPM (R 4.0.3) yaml 2.2.1 2020-02-01 [1] RSPM (R 4.0.3) [1] /home/rstudio-user/R/x86_64-pc-linux-gnu-library/4.0 [2] /opt/R/4.0.3/lib/R/library ```
yonicd commented 3 years ago

i tried that again restarting each time.

no duplicate elements:

duplicate elements:

What is the internal browser of the RS desktop IDE on the osx?

I also similar behavior on GHA workflows and couldnt understand why my reactivity counts were different when running reactivity tests.

session info ```r ─ Session info ───────────────────────────────────────────────────────────────────── setting value version R version 3.6.3 (2020-02-29) os macOS Catalina 10.15.7 system x86_64, darwin15.6.0 ui RStudio language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz America/New_York date 2020-12-23 ─ Packages ───────────────────────────────────────────────────────────────────────── package * version date lib source assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) attempt 0.3.1 2020-05-03 [1] CRAN (R 3.6.2) cli 2.2.0 2020-11-20 [1] CRAN (R 3.6.2) clipr 0.7.1 2020-10-08 [1] CRAN (R 3.6.2) codetools 0.2-16 2018-12-24 [1] CRAN (R 3.6.3) colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.0) config 0.3 2018-03-27 [1] CRAN (R 3.6.0) crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) curl 4.3 2019-12-02 [1] CRAN (R 3.6.0) deldir 0.2-3 2020-11-09 [1] CRAN (R 3.6.2) desc 1.2.0.9000 2020-09-28 [1] Github (r-lib/desc@c175259) details 0.2.1 2020-01-12 [1] local digest 0.6.27 2020-10-24 [1] CRAN (R 3.6.2) dockerfiler 0.1.3 2019-03-19 [1] CRAN (R 3.6.0) dplyr 1.0.2 2020-08-18 [1] CRAN (R 3.6.2) ellipsis 0.3.1 2020-05-15 [1] CRAN (R 3.6.2) fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) farver 2.0.3 2020-01-16 [1] CRAN (R 3.6.0) fastmap 1.0.1 2019-10-08 [1] CRAN (R 3.6.0) fs 1.5.0 2020-07-31 [1] CRAN (R 3.6.2) generics 0.0.2 2018-11-29 [1] CRAN (R 3.6.0) ggplot2 3.3.2 2020-06-19 [1] CRAN (R 3.6.2) ggvoronoi 0.8.3 2019-02-19 [1] CRAN (R 3.6.0) glue 1.4.2 2020-08-27 [1] CRAN (R 3.6.2) golem 0.3.0 2020-12-06 [1] local gridExtra 2.3 2017-09-09 [1] CRAN (R 3.6.0) gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.0) htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.2) httpuv 1.5.4 2020-06-06 [1] CRAN (R 3.6.2) httr 1.4.2 2020-07-20 [1] CRAN (R 3.6.2) jsonlite 1.7.2 2020-12-09 [1] CRAN (R 3.6.2) knitr 1.30 2020-09-22 [1] CRAN (R 3.6.2) labeling 0.3 2014-08-23 [1] CRAN (R 3.6.0) later 1.1.0.9000 2020-12-12 [1] Github (r-lib/later@ff8c451) lattice 0.20-38 2018-11-04 [1] CRAN (R 3.6.3) lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.0) magick 2.2 2019-08-26 [1] CRAN (R 3.6.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 3.6.2) mime 0.9 2020-02-04 [1] CRAN (R 3.6.0) munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.0) pillar 1.4.7 2020-11-20 [1] CRAN (R 3.6.2) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.0) pkgload 1.1.0 2020-05-29 [1] CRAN (R 3.6.2) png 0.1-7 2013-12-03 [1] CRAN (R 3.6.0) promises 1.1.1.9001 2020-11-25 [1] Github (rstudio/promises@bbadb3d) purrr 0.3.4 2020-04-17 [1] CRAN (R 3.6.2) puzzlemath 0.0.3 2020-12-22 [1] local R6 2.5.0 2020-10-28 [1] CRAN (R 3.6.2) raster 3.4-5 2020-11-14 [1] CRAN (R 3.6.2) Rcpp 1.0.5 2020-07-06 [1] CRAN (R 3.6.2) reactlog 1.1.0 2020-09-12 [1] CRAN (R 3.6.2) remotes 2.2.0 2020-07-21 [1] CRAN (R 3.6.2) rgeos 0.5-3 2020-05-08 [1] CRAN (R 3.6.2) rlang 0.4.9 2020-11-26 [1] CRAN (R 3.6.2) roxygen2 7.1.1 2020-06-27 [1] CRAN (R 3.6.2) rprojroot 2.0.2 2020-11-25 [1] Github (r-lib/rprojroot@5bafca9) rstudioapi 0.13 2020-11-12 [1] CRAN (R 3.6.2) scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.0) sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0) shiny * 1.5.0 2020-06-23 [1] CRAN (R 3.6.2) shinyjs 1.0 2018-01-08 [1] CRAN (R 3.6.0) shinyWidgets 0.5.0 2019-11-18 [1] CRAN (R 3.6.0) sp 1.4-4 2020-10-07 [1] CRAN (R 3.6.2) stringi 1.5.3 2020-09-09 [1] CRAN (R 3.6.2) stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) testthat 3.0.0 2020-10-31 [1] CRAN (R 3.6.2) tibble 3.0.4 2020-10-12 [1] CRAN (R 3.6.2) tidyselect 1.1.0 2020-05-11 [1] CRAN (R 3.6.2) usethis 1.9.0.9000 2020-11-25 [1] Github (r-lib/usethis@2a7ee3b) vctrs 0.3.5 2020-11-17 [1] CRAN (R 3.6.2) viridis 0.5.1 2018-03-29 [1] CRAN (R 3.6.0) viridisLite 0.3.0 2018-02-01 [1] CRAN (R 3.6.0) whereami 0.1.9 2020-09-24 [1] local withr 2.3.0 2020-09-22 [1] CRAN (R 3.6.2) xfun 0.19 2020-10-30 [1] CRAN (R 3.6.2) xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.2) xtable 1.8-4 2019-04-21 [1] CRAN (R 3.6.0) yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library ```


wch commented 3 years ago

I see the same thing in Firefox that I did in Chrome.

image

This is with the app running in rstudio.cloud.

The RStudio IDE on Mac is based on Chromium, I believe.

It's not clear to me how you're using firefox to visit the app, but I suspect that it's hitting the app twice. You could add some code to your server function to write a timestamp to a file every time the server function is executed; then you can see how many times the app is being hit. You can also use options(shiny.trace=TRUE) to see the network traffic.

yonicd commented 3 years ago

I’ll try that, thanks for digging into this.

yonicd commented 3 years ago

not sure what i am seeing here, you probably know better to spot what is happening.

It seems like in firefox the action button game was hit after the question was created and put in ques and in chrome this isnt happening.

set chrome as default browser and run app

query in terminal the default browser

yonis@Yonis-MacBook-Pro ~ % x=~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist; \
plutil -convert xml1 $x; \
grep 'https' -b3 $x | awk 'NR==2 {split($2, arr, "[><]"); print arr[3]}'; \
plutil -convert binary1 $x
com.google.chrome
Restarting R session...

> options(shiny.trace=TRUE)
> options(shiny.launch.browser = .rs.invokeShinyWindowExternal)
> shiny::reactlogReset()
> shiny::shinyApp(
+   ui = puzzlemath:::app_ui, 
+   server = puzzlemath:::app_server
+ )
Loading required package: shiny

Listening on http://127.0.0.1:7183
SEND {"config":{"workerId":"","sessionId":"9a71839f391a1fead621fbad4db7dad9","user":null}}
RECV {"method":"init","data":{"signs":["+","-","*","/"],"game:shiny.action":0,"draw:shiny.action":0,"range":[1,10],"n":25,"ans":"",".clientdata_output_plot1-plot_width":930,".clientdata_output_plot1-plot_height":500,".clientdata_output_plot1-plot_bg":"rgb(255, 255, 255)",".clientdata_output_plot1-plot_fg":"rgb(51, 51, 51)",".clientdata_output_plot1-plot_accent":"rgb(51, 122, 183)",".clientdata_output_plot1-plot_font":{"families":["Helvetica Neue","Helvetica","Arial","sans-serif"],"size":"14px"},".clientdata_output_ques_hidden":false,".clientdata_output_plot1-plot_hidden":false,".clientdata_output_tbl_hidden":true,".clientdata_pixelratio":2,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"7183",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"603e796bcfc2ab3685167d58c426f64c15a95192",".clientdata_allowDataUriScheme":true}}
SEND {"busy":"busy"}
SEND {"custom":{"shinyjs-show":{"id":"draw","anim":false,"animType":"slide","time":0.5,"selector":null}}}
SEND {"custom":{"shinyjs-click":{"id":"game"}}}
SEND {"custom":{"shinyjs-click":{"id":"game"}}}
SEND {"custom":{"shinyjs-runjs":{"code":"document.getElementById('anspanel').style.borderColor = 'grey'"}}}
SEND {"custom":{"shinyjs-runjs":{"code":"document.getElementById('anspanel').style.borderWidth = '1px'"}}}
SEND {"recalculating":{"name":"plot1-plot","status":"recalculating"}}
SEND {"custom":{"shinyjs-logjs":{"text":"plot"}}}
── Running `shiny::renderPlot`(...) at mod_plot.R#31 (1) ─────────────────────────────
SEND {"recalculating":{"name":"plot1-plot","status":"recalculated"}}
SEND {"busy":"idle"}
SEND {"errors":{},"values":{"plot1-plot":{"src":"data:image/png;[base64 data]","width":930,"height":500,"coordmap":{"panels":[{"panel":1,"row":1,"col":1,"panel_vars":{},"log":{"x":null,"y":null},"domain":{"left":-123.6,"right":1995.6,"bottom":3.8,"top":2178.2},"mapping":{"x":"xx","y":"yy"},"range":{"left":16.4383561643836,"right":1849.04109589041,"bottom":983.561643835616,"top":10.958904109589}}],"dims":{"width":1860,"height":1000}}}},"inputMessages":[]}
RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
SEND {"busy":"busy"}
SEND {"custom":{"shinyjs-show":{"id":"draw","anim":false,"animType":"slide","time":0.5,"selector":null}}}
── Running observeEventHandler(...) at app_server.R#36 (1) ───────────────────────────
SEND {"recalculating":{"name":"ques","status":"recalculating"}}
SEND {"recalculating":{"name":"ques","status":"recalculated"}}
SEND {"busy":"idle"}
SEND {"errors":{},"values":{"ques":"8 * 6 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}

set default browser to firefox and rerun app

yonis@Yonis-MacBook-Pro ~ % x=~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist; \
plutil -convert xml1 $x; \
grep 'https' -b3 $x | awk 'NR==2 {split($2, arr, "[><]"); print arr[3]}'; \
plutil -convert binary1 $x
org.mozilla.firefox
Restarting R session...

> library(puzzlemath)
> options(shiny.trace=TRUE)
> options(shiny.launch.browser = .rs.invokeShinyWindowExternal)
> shiny::reactlogReset()
> shiny::shinyApp(
+   ui = puzzlemath:::app_ui, 
+   server = puzzlemath:::app_server
+ )

Listening on http://127.0.0.1:7620
SEND {"config":{"workerId":"","sessionId":"3100565c0a54718fd6eecbddb09d9153","user":null}}
RECV {"method":"init","data":{"signs":["+","-","*","/"],"game:shiny.action":0,"draw:shiny.action":0,"range":[1,10],"n":25,"ans":"",".clientdata_output_plot1-plot_width":930,".clientdata_output_plot1-plot_height":500,".clientdata_output_plot1-plot_bg":"rgb(255, 255, 255)",".clientdata_output_plot1-plot_fg":"rgb(51, 51, 51)",".clientdata_output_plot1-plot_accent":"rgb(51, 122, 183)",".clientdata_output_plot1-plot_font":{"families":["Helvetica Neue","Helvetica","Arial","sans-serif"],"size":"14px"},".clientdata_output_ques_hidden":false,".clientdata_output_plot1-plot_hidden":false,".clientdata_output_tbl_hidden":true,".clientdata_pixelratio":2,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"7620",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"603e796bcfc2ab3685167d58c426f64c15a95192",".clientdata_allowDataUriScheme":true}}
SEND {"busy":"busy"}
SEND {"custom":{"shinyjs-show":{"id":"draw","anim":false,"animType":"slide","time":0.5,"selector":null}}}
SEND {"custom":{"shinyjs-click":{"id":"game"}}}
SEND {"custom":{"shinyjs-click":{"id":"game"}}}
SEND {"custom":{"shinyjs-runjs":{"code":"document.getElementById('anspanel').style.borderColor = 'grey'"}}}
SEND {"custom":{"shinyjs-runjs":{"code":"document.getElementById('anspanel').style.borderWidth = '1px'"}}}
SEND {"recalculating":{"name":"plot1-plot","status":"recalculating"}}
SEND {"custom":{"shinyjs-logjs":{"text":"plot"}}}
── Running `shiny::renderPlot`(...) at mod_plot.R#31 (1) ─────────────────────────────
SEND {"recalculating":{"name":"plot1-plot","status":"recalculated"}}
SEND {"busy":"idle"}
SEND {"errors":{},"values":{"plot1-plot":{"src":"data:image/png;[base64 data]","width":930,"height":500,"coordmap":{"panels":[{"panel":1,"row":1,"col":1,"panel_vars":{},"log":{"x":null,"y":null},"domain":{"left":-164.4,"right":2180.4,"bottom":-160.6,"top":2174.6},"mapping":{"x":"xx","y":"yy"},"range":{"left":16.4383561643836,"right":1849.04109589041,"bottom":983.561643835616,"top":10.958904109589}}],"dims":{"width":1860,"height":1000}}}},"inputMessages":[]}
RECV {"method":"update","data":{"game:shiny.action":1,"draw:shiny.action":1}}
SEND {"busy":"busy"}
SEND {"custom":{"shinyjs-show":{"id":"draw","anim":false,"animType":"slide","time":0.5,"selector":null}}}
── Running observeEventHandler(...) at app_server.R#36 (1) ───────────────────────────
SEND {"recalculating":{"name":"ques","status":"recalculating"}}
SEND {"recalculating":{"name":"ques","status":"recalculated"}}
SEND {"busy":"idle"}
SEND {"errors":{},"values":{"ques":"8 * 5 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}
RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
SEND {"busy":"busy"}
SEND {"custom":{"shinyjs-show":{"id":"draw","anim":false,"animType":"slide","time":0.5,"selector":null}}}
── Running observeEventHandler(...) at app_server.R#36 (2) ───────────────────────────
SEND {"progress":{"type":"binding","message":{"id":"ques"}}}
SEND {"recalculating":{"name":"ques","status":"recalculating"}}
SEND {"recalculating":{"name":"ques","status":"recalculated"}}
SEND {"busy":"idle"}
SEND {"errors":{},"values":{"ques":"10 - 4 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}
yonicd commented 3 years ago

I also added

app_server <- function( input, output, session ) {
  cat(Sys.time(),file = 'timestamp.txt',append = TRUE,sep = '\n')
...
}

and got back only one hit per run

1608782552 # chrome
1608782612 # firefox
yonicd commented 3 years ago

Here is the GHA test of the same setup (using reactor), showing this isnt constrained to the local machine that I am using.

testthat setup: https://github.com/yonicd/puzzlemath/blob/main/tests/testthat/reactor-initial.R gha workflow: https://github.com/yonicd/puzzlemath/blob/main/.github/workflows/R-reactor.yml gha output: https://github.com/yonicd/puzzlemath/runs/1603764213?check_suite_focus=true#step:7:33

these unit test are checking the same thing as above, how many times have {whereami} calls been hit after initial invalidation. Which in this case is the same reactive chunk that contains output$ques. This is consistent with what reactlog and shiny.trace are tracking.

wch commented 3 years ago

At this point, I suggest making a truly minimal reproducible example -- without shinyjs, without reactor, etc. Given what we know at this point, it could be due to shinyjs, or perhaps even the order that JS files are loaded, so it would be best to remove as many variables as possible.

yonicd commented 3 years ago

Will do. I’m wo a computer for the week, so I’ll pick this up after the new year. Happy Holidays!

yonicd commented 3 years ago

So i removed shinyjs and am using native session$sendCustomMessages with message handlers defined in inst/app/script.js

here is a reprex using RSelenium and processx, which is consistent with the GHA tests that are run too.

I think the difference is coming from these lines, where if i turn off one of the customMessages then the initialization is the same.

#remotes::install_github('yonicd/puzzlemath@rm_shinyjs')
testdir <- file.path(tempdir(),'test')

dir.create(testdir,showWarnings = FALSE)

process_args <- c(
  "options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE)",
  "library(puzzlemath)",
  "packageVersion('puzzlemath')",
  "puzzlemath::run_app()"
  )

test_process <- processx::process$new(
  command = normalizePath(file.path(Sys.getenv("R_HOME"),'R')), 
  args    = c("-e", paste0(process_args,collapse = ';')),
  stderr  = file.path(testdir,'err.txt'),
  stdout  = file.path(testdir,'out.txt')
)

gecko_driver <-   RSelenium::rsDriver(
  browser = "firefox",
  verbose = FALSE,
  port = httpuv::randomPort(),
  extraCapabilities = list(
    "moz:firefoxOptions" = list(
      args = c("--headless",'--memory 1024mb')
    )
  )
)

gecko_driver$client$navigate('http://127.0.0.1:26877')

Sys.sleep(5)

cat(readLines(file.path(testdir,'out.txt')),sep = '\n')
#> 
#> R version 3.6.3 (2020-02-29) -- "Holding the Windsock"
#> Copyright (C) 2020 The R Foundation for Statistical Computing
#> Platform: x86_64-apple-darwin15.6.0 (64-bit)
#> 
#> R is free software and comes with ABSOLUTELY NO WARRANTY.
#> You are welcome to redistribute it under certain conditions.
#> Type 'license()' or 'licence()' for distribution details.
#> 
#>   Natural language support but running in an English locale
#> 
#> R is a collaborative project with many contributors.
#> Type 'contributors()' for more information and
#> 'citation()' on how to cite R or R packages in publications.
#> 
#> Type 'demo()' for some demos, 'help()' for on-line help, or
#> 'help.start()' for an HTML browser interface to help.
#> Type 'q()' to quit R.
#> 
#> > options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE);library(puzzlemath);packageVersion('puzzlemath');puzzlemath::run_app()
#> [1] ‘0.0.4’
#> ── Running `shiny::renderPlot`(...) at mod_plot.R#31 (1) ───────────────────────
#> ── Running observeEventHandler(...) at app_server.R#35 (1) ─────────────────────
#> ── Running observeEventHandler(...) at app_server.R#35 (2) ─────────────────────
cat(readLines(file.path(testdir,'err.txt')),sep = '\n')
#> Loading required package: shiny
#> 
#> Listening on http://127.0.0.1:26877
#> SEND {"config":{"workerId":"","sessionId":"a16b03167f173f2a8495cb5afc2592a7","user":null}}
#> RECV {"method":"init","data":{"signs":["+","-","*","/"],"game:shiny.action":0,"draw:shiny.action":0,"range":[1,10],"n":25,"ans":"",".clientdata_output_plot1-plot_width":881,".clientdata_output_plot1-plot_height":500,".clientdata_output_plot1-plot_bg":"rgb(255, 255, 255)",".clientdata_output_plot1-plot_fg":"rgb(51, 51, 51)",".clientdata_output_plot1-plot_accent":"rgb(51, 122, 183)",".clientdata_output_plot1-plot_font":{"families":["Helvetica Neue","Helvetica","Arial","sans-serif"],"size":"14px"},".clientdata_output_ques_hidden":false,".clientdata_output_plot1-plot_hidden":false,".clientdata_output_tbl_hidden":true,".clientdata_pixelratio":1,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"26877",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"eval":"document.getElementById('anspanel').style.borderColor = 'grey'"}}
#> SEND {"custom":{"eval":"document.getElementById('anspanel').style.borderWidth = '1px'"}}
#> SEND {"recalculating":{"name":"plot1-plot","status":"recalculating"}}
#> SEND {"recalculating":{"name":"plot1-plot","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"plot1-plot":{"src":"data:image/png;[base64 data]","width":881,"height":500,"coordmap":{"panels":[{"panel":1,"row":1,"col":1,"panel_vars":{},"log":{"x":null,"y":null},"domain":{"left":-143.2,"right":2127.2,"bottom":-136.9,"top":2129.9},"mapping":{"x":"xx","y":"yy"},"range":{"left":8.21917808219178,"right":875.520547945206,"bottom":491.780821917808,"top":5.47945205479452}}],"dims":{"width":881,"height":500}}}},"inputMessages":[]}
#> RECV {"method":"update","data":{"game:shiny.action":1,"draw:shiny.action":1}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"9 + 7 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}
#> RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"progress":{"type":"binding","message":{"id":"ques"}}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"8 / 1 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}

gecko_driver$server$stop()
#> [1] TRUE
test_process$kill()
#> [1] TRUE

test_process <- processx::process$new(
  command = normalizePath(file.path(Sys.getenv("R_HOME"),'R')), 
  args    = c("-e", paste0(process_args,collapse = ';')),
  stderr  = file.path(testdir,'err.txt'),
  stdout  = file.path(testdir,'out.txt')
)

chrome_driver <-   RSelenium::rsDriver(
  browser = "chrome",
  verbose = FALSE,
  chromever = "87.0.4280.88",
  port = httpuv::randomPort(),
  extraCapabilities = list(
    chromeOptions = list(
      args = c("--headless","--disable-gpu")
    )
  )
)

chrome_driver$client$navigate('http://127.0.0.1:26877')

Sys.sleep(5)

cat(readLines(file.path(testdir,'out.txt')),sep = '\n')
#> 
#> R version 3.6.3 (2020-02-29) -- "Holding the Windsock"
#> Copyright (C) 2020 The R Foundation for Statistical Computing
#> Platform: x86_64-apple-darwin15.6.0 (64-bit)
#> 
#> R is free software and comes with ABSOLUTELY NO WARRANTY.
#> You are welcome to redistribute it under certain conditions.
#> Type 'license()' or 'licence()' for distribution details.
#> 
#>   Natural language support but running in an English locale
#> 
#> R is a collaborative project with many contributors.
#> Type 'contributors()' for more information and
#> 'citation()' on how to cite R or R packages in publications.
#> 
#> Type 'demo()' for some demos, 'help()' for on-line help, or
#> 'help.start()' for an HTML browser interface to help.
#> Type 'q()' to quit R.
#> 
#> > options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE);library(puzzlemath);packageVersion('puzzlemath');puzzlemath::run_app()
#> [1] ‘0.0.4’
#> ── Running `shiny::renderPlot`(...) at mod_plot.R#31 (1) ───────────────────────
#> ── Running observeEventHandler(...) at app_server.R#35 (1) ─────────────────────
cat(readLines(file.path(testdir,'err.txt')),sep = '\n')
#> Loading required package: shiny
#> 
#> Listening on http://127.0.0.1:26877
#> SEND {"config":{"workerId":"","sessionId":"ab0780efa6048fba4d4b6d8227e6a319","user":null}}
#> RECV {"method":"init","data":{"signs":["+","-","*","/"],"game:shiny.action":0,"draw:shiny.action":0,"range":[1,10],"n":25,"ans":"",".clientdata_output_plot1-plot_width":503,".clientdata_output_plot1-plot_height":500,".clientdata_output_plot1-plot_bg":"rgb(255, 255, 255)",".clientdata_output_plot1-plot_fg":"rgb(51, 51, 51)",".clientdata_output_plot1-plot_accent":"rgb(51, 122, 183)",".clientdata_output_plot1-plot_font":{"families":["Helvetica Neue","Helvetica","Arial","sans-serif"],"size":"14px"},".clientdata_output_ques_hidden":false,".clientdata_output_plot1-plot_hidden":false,".clientdata_output_tbl_hidden":true,".clientdata_pixelratio":2,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"26877",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"eval":"document.getElementById('anspanel').style.borderColor = 'grey'"}}
#> SEND {"custom":{"eval":"document.getElementById('anspanel').style.borderWidth = '1px'"}}
#> SEND {"recalculating":{"name":"plot1-plot","status":"recalculating"}}
#> SEND {"recalculating":{"name":"plot1-plot","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"plot1-plot":{"src":"data:image/png;[base64 data]","width":503,"height":500,"coordmap":{"panels":[{"panel":1,"row":1,"col":1,"panel_vars":{},"log":{"x":null,"y":null},"domain":{"left":-137.4,"right":1967.4,"bottom":104.1,"top":2166.9},"mapping":{"x":"xx","y":"yy"},"range":{"left":16.4383561643836,"right":995.041095890411,"bottom":983.561643835616,"top":10.958904109589}}],"dims":{"width":1006,"height":1000}}}},"inputMessages":[]}
#> RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"9 * 2 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}

chrome_driver$server$stop()
#> [1] TRUE
test_process$kill()
#> [1] TRUE

library(puzzlemath)
details::details(sessioninfo::session_info(),summary = 'sessioninfo')
sessioninfo ```r ─ Session info ───────────────────────────────────────────────────────────────────────────────────── setting value version R version 3.6.3 (2020-02-29) os macOS Catalina 10.15.7 system x86_64, darwin15.6.0 ui RStudio language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz America/New_York date 2021-01-01 ─ Packages ───────────────────────────────────────────────────────────────────────────────────────── package * version date lib source assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) attempt 0.3.1 2020-05-03 [1] CRAN (R 3.6.2) callr 3.5.1 2020-10-13 [1] CRAN (R 3.6.2) cli 2.2.0 2020-11-20 [1] CRAN (R 3.6.2) clipr 0.7.1 2020-10-08 [1] CRAN (R 3.6.2) codetools 0.2-16 2018-12-24 [1] CRAN (R 3.6.3) colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.0) config 0.3 2018-03-27 [1] CRAN (R 3.6.0) crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) deldir 0.2-3 2020-11-09 [1] CRAN (R 3.6.2) desc 1.2.0.9000 2020-09-28 [1] Github (r-lib/desc@c175259) details 0.2.1 2020-01-12 [1] local digest 0.6.27 2020-10-24 [1] CRAN (R 3.6.2) dockerfiler 0.1.3 2019-03-19 [1] CRAN (R 3.6.0) dplyr 1.0.2 2020-08-18 [1] CRAN (R 3.6.2) ellipsis 0.3.1 2020-05-15 [1] CRAN (R 3.6.2) evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0) fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) fastmap 1.0.1 2019-10-08 [1] CRAN (R 3.6.0) fs 1.5.0 2020-07-31 [1] CRAN (R 3.6.2) generics 0.0.2 2018-11-29 [1] CRAN (R 3.6.0) ggplot2 3.3.2 2020-06-19 [1] CRAN (R 3.6.2) ggvoronoi 0.8.3 2019-02-19 [1] CRAN (R 3.6.0) glue 1.4.2 2020-08-27 [1] CRAN (R 3.6.2) golem 0.3.0 2020-12-06 [1] local gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.0) htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.2) httpuv 1.5.4 2020-06-06 [1] CRAN (R 3.6.2) httr 1.4.2 2020-07-20 [1] CRAN (R 3.6.2) jsonlite 1.7.2 2020-12-09 [1] CRAN (R 3.6.2) knitr 1.30 2020-09-22 [1] CRAN (R 3.6.2) later 1.1.0.9000 2020-12-12 [1] Github (r-lib/later@ff8c451) lattice 0.20-38 2018-11-04 [1] CRAN (R 3.6.3) lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.0) magick 2.2 2019-08-26 [1] CRAN (R 3.6.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 3.6.2) mime 0.9 2020-02-04 [1] CRAN (R 3.6.0) munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.0) pillar 1.4.7 2020-11-20 [1] CRAN (R 3.6.2) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.0) pkgload 1.1.0 2020-05-29 [1] CRAN (R 3.6.2) png 0.1-7 2013-12-03 [1] CRAN (R 3.6.0) processx 3.4.5 2020-11-30 [1] CRAN (R 3.6.2) promises 1.1.1.9001 2020-11-25 [1] Github (rstudio/promises@bbadb3d) ps 1.5.0 2020-12-05 [1] CRAN (R 3.6.2) purrr 0.3.4 2020-04-17 [1] CRAN (R 3.6.2) puzzlemath * 0.0.4 2021-01-02 [1] local R6 2.5.0 2020-10-28 [1] CRAN (R 3.6.2) raster 3.4-5 2020-11-14 [1] CRAN (R 3.6.2) Rcpp 1.0.5 2020-07-06 [1] CRAN (R 3.6.2) remotes 2.2.0 2020-07-21 [1] CRAN (R 3.6.2) reprex 0.3.0 2019-05-16 [1] CRAN (R 3.6.0) rgeos 0.5-3 2020-05-08 [1] CRAN (R 3.6.2) rlang 0.4.9 2020-11-26 [1] CRAN (R 3.6.2) rmarkdown 2.5 2020-10-21 [1] CRAN (R 3.6.3) roxygen2 7.1.1 2020-06-27 [1] CRAN (R 3.6.2) rprojroot 2.0.2 2020-11-25 [1] Github (r-lib/rprojroot@5bafca9) rstudioapi 0.13 2020-11-12 [1] CRAN (R 3.6.2) scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.0) sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0) shiny 1.5.0 2020-06-23 [1] CRAN (R 3.6.2) shinyWidgets 0.5.0 2019-11-18 [1] CRAN (R 3.6.0) sp 1.4-4 2020-10-07 [1] CRAN (R 3.6.2) stringi 1.5.3 2020-09-09 [1] CRAN (R 3.6.2) stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) testthat 3.0.0 2020-10-31 [1] CRAN (R 3.6.2) tibble 3.0.4 2020-10-12 [1] CRAN (R 3.6.2) tidyselect 1.1.0 2020-05-11 [1] CRAN (R 3.6.2) usethis 1.9.0.9000 2020-11-25 [1] Github (r-lib/usethis@2a7ee3b) vctrs 0.3.5 2020-11-17 [1] CRAN (R 3.6.2) whereami 0.1.9 2020-09-24 [1] local whisker 0.4 2019-08-28 [1] CRAN (R 3.6.1) withr 2.3.0 2020-09-22 [1] CRAN (R 3.6.2) xfun 0.19 2020-10-30 [1] CRAN (R 3.6.2) xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.2) xtable 1.8-4 2019-04-21 [1] CRAN (R 3.6.0) yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library ```


Created on 2021-01-01 by the reprex package (v0.3.0)

yonicd commented 3 years ago

i trimmed out a lot of the uneccessary parts of the app and moved the app into a more standard global/server/ui format to make it simpler to reprex on your side.

files are in inst/app

#remotes::install_github('yonicd/puzzlemath@rm_shinyjs')
testdir <- file.path(tempdir(),'test')

dir.create(testdir,showWarnings = FALSE)

process_args <- c(
  "options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE)",
  "library(puzzlemath)",
  "packageVersion('puzzlemath')",
  "shiny::runApp(system.file('app',package = 'puzzlemath'))"
  )

test_process <- processx::process$new(
  command = normalizePath(file.path(Sys.getenv("R_HOME"),'R')), 
  args    = c("-e", paste0(process_args,collapse = ';')),
  stderr  = file.path(testdir,'err.txt'),
  stdout  = file.path(testdir,'out.txt')
)

gecko_driver <-   RSelenium::rsDriver(
  browser = "firefox",
  verbose = FALSE,
  port = httpuv::randomPort(),
  extraCapabilities = list(
    "moz:firefoxOptions" = list(
      args = c("--headless",'--memory 1024mb')
    )
  )
)

gecko_driver$client$navigate('http://127.0.0.1:26877')

Sys.sleep(5)

cat(readLines(file.path(testdir,'out.txt')),sep = '\n')
#> 
#> R version 3.6.3 (2020-02-29) -- "Holding the Windsock"
#> Copyright (C) 2020 The R Foundation for Statistical Computing
#> Platform: x86_64-apple-darwin15.6.0 (64-bit)
#> 
#> R is free software and comes with ABSOLUTELY NO WARRANTY.
#> You are welcome to redistribute it under certain conditions.
#> Type 'license()' or 'licence()' for distribution details.
#> 
#>   Natural language support but running in an English locale
#> 
#> R is a collaborative project with many contributors.
#> Type 'contributors()' for more information and
#> 'citation()' on how to cite R or R packages in publications.
#> 
#> Type 'demo()' for some demos, 'help()' for on-line help, or
#> 'help.start()' for an HTML browser interface to help.
#> Type 'q()' to quit R.
#> 
#> > options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE);library(puzzlemath);packageVersion('puzzlemath');shiny::runApp(system.file('app',package = 'puzzlemath'))
#> [1] ‘0.0.4’
#> ── Running observeEventHandler(...) at server.R#25 (1) ─────────────────────────
#> ── Running observeEventHandler(...) at server.R#25 (2) ─────────────────────────
cat(readLines(file.path(testdir,'err.txt')),sep = '\n')
#> Loading required package: shiny
#> 
#> Listening on http://127.0.0.1:26877
#> SEND {"config":{"workerId":"","sessionId":"5a01640cafb0baa09f86a6aea2684ffb","user":null}}
#> RECV {"method":"init","data":{"game:shiny.action":0,"draw:shiny.action":0,"signs":["+","-","*","/"],"range":[1,10],"n":25,"ans":"",".clientdata_output_ques_hidden":false,".clientdata_pixelratio":1,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"26877",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{},"inputMessages":[]}
#> RECV {"method":"update","data":{"game:shiny.action":1,"draw:shiny.action":1}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"8 + 6 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}
#> RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"progress":{"type":"binding","message":{"id":"ques"}}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"10 / 2 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}

gecko_driver$server$stop()
#> [1] TRUE
test_process$kill()
#> [1] TRUE

test_process <- processx::process$new(
  command = normalizePath(file.path(Sys.getenv("R_HOME"),'R')), 
  args    = c("-e", paste0(process_args,collapse = ';')),
  stderr  = file.path(testdir,'err.txt'),
  stdout  = file.path(testdir,'out.txt')
)

chrome_driver <-   RSelenium::rsDriver(
  browser = "chrome",
  verbose = FALSE,
  chromever = "87.0.4280.88",
  port = httpuv::randomPort(),
  extraCapabilities = list(
    chromeOptions = list(
      args = c("--headless","--disable-gpu")
    )
  )
)

chrome_driver$client$navigate('http://127.0.0.1:26877')

Sys.sleep(5)

cat(readLines(file.path(testdir,'out.txt')),sep = '\n')
#> 
#> R version 3.6.3 (2020-02-29) -- "Holding the Windsock"
#> Copyright (C) 2020 The R Foundation for Statistical Computing
#> Platform: x86_64-apple-darwin15.6.0 (64-bit)
#> 
#> R is free software and comes with ABSOLUTELY NO WARRANTY.
#> You are welcome to redistribute it under certain conditions.
#> Type 'license()' or 'licence()' for distribution details.
#> 
#>   Natural language support but running in an English locale
#> 
#> R is a collaborative project with many contributors.
#> Type 'contributors()' for more information and
#> 'citation()' on how to cite R or R packages in publications.
#> 
#> Type 'demo()' for some demos, 'help()' for on-line help, or
#> 'help.start()' for an HTML browser interface to help.
#> Type 'q()' to quit R.
#> 
#> > options('shiny.port'= 26877, shiny.host='127.0.0.1', shiny.trace = TRUE);library(puzzlemath);packageVersion('puzzlemath');shiny::runApp(system.file('app',package = 'puzzlemath'))
#> [1] ‘0.0.4’
#> ── Running observeEventHandler(...) at server.R#25 (1) ─────────────────────────
cat(readLines(file.path(testdir,'err.txt')),sep = '\n')
#> Loading required package: shiny
#> 
#> Listening on http://127.0.0.1:26877
#> SEND {"config":{"workerId":"","sessionId":"390366c4c826735831fc9a64ce069ab2","user":null}}
#> RECV {"method":"init","data":{"game:shiny.action":0,"draw:shiny.action":0,"signs":["+","-","*","/"],"range":[1,10],"n":25,"ans":"",".clientdata_output_ques_hidden":false,".clientdata_pixelratio":2,".clientdata_url_protocol":"http:",".clientdata_url_hostname":"127.0.0.1",".clientdata_url_port":"26877",".clientdata_url_pathname":"/",".clientdata_url_search":"",".clientdata_url_hash_initial":"",".clientdata_url_hash":"",".clientdata_singletons":"",".clientdata_allowDataUriScheme":true}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"custom":{"clickon":"#game"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{},"inputMessages":[]}
#> RECV {"method":"update","data":{"game:shiny.action":2,"draw:shiny.action":2}}
#> SEND {"busy":"busy"}
#> SEND {"custom":{"showid":"draw"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculating"}}
#> SEND {"recalculating":{"name":"ques","status":"recalculated"}}
#> SEND {"busy":"idle"}
#> SEND {"errors":{},"values":{"ques":"8 * 3 ?"},"inputMessages":[{"id":"ans","message":{"value":""}}]}

chrome_driver$server$stop()
#> [1] TRUE
test_process$kill()
#> [1] TRUE

details::details(sessioninfo::session_info(),summary = 'sessioninfo')
sessioninfo ``` r ─ Session info ─────────────────────────────────────────────────────────────── setting value version R version 3.6.3 (2020-02-29) os macOS Catalina 10.15.7 system x86_64, darwin15.6.0 ui X11 language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz America/New_York date 2021-01-04 ─ Packages ─────────────────────────────────────────────────────────────────── package * version date lib source askpass 1.1 2019-01-13 [1] CRAN (R 3.6.0) assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) binman 0.1.1 2018-07-18 [1] CRAN (R 3.6.0) bitops 1.0-6 2013-08-17 [1] CRAN (R 3.6.0) caTools 1.18.0 2020-01-17 [1] CRAN (R 3.6.0) cli 2.2.0 2020-11-20 [1] CRAN (R 3.6.2) clipr 0.7.1 2020-10-08 [1] CRAN (R 3.6.2) crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) curl 4.3 2019-12-02 [1] CRAN (R 3.6.0) desc 1.2.0.9000 2020-09-28 [1] Github (r-lib/desc@c175259) details 0.2.1 2020-01-12 [1] local digest 0.6.27 2020-10-24 [1] CRAN (R 3.6.2) evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0) fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) glue 1.4.2 2020-08-27 [1] CRAN (R 3.6.2) highr 0.8 2019-03-20 [1] CRAN (R 3.6.0) htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.2) httpuv 1.5.4 2020-06-06 [1] CRAN (R 3.6.2) httr 1.4.2 2020-07-20 [1] CRAN (R 3.6.2) jsonlite 1.7.2 2020-12-09 [1] CRAN (R 3.6.2) knitr 1.30 2020-09-22 [1] CRAN (R 3.6.2) later 1.1.0.9000 2020-12-12 [1] Github (r-lib/later@ff8c451) magrittr 2.0.1 2020-11-17 [1] CRAN (R 3.6.2) openssl 1.4.3 2020-09-18 [1] CRAN (R 3.6.2) png 0.1-7 2013-12-03 [1] CRAN (R 3.6.0) processx 3.4.5 2020-11-30 [1] CRAN (R 3.6.2) promises 1.1.1.9001 2020-11-25 [1] Github (rstudio/promises@bbadb3d) ps 1.5.0 2020-12-05 [1] CRAN (R 3.6.2) R6 2.5.0 2020-10-28 [1] CRAN (R 3.6.2) rappdirs 0.3.1 2016-03-28 [1] CRAN (R 3.6.0) Rcpp 1.0.5 2020-07-06 [1] CRAN (R 3.6.2) rlang 0.4.9 2020-11-26 [1] CRAN (R 3.6.2) rmarkdown 2.5 2020-10-21 [1] CRAN (R 3.6.3) rprojroot 2.0.2 2020-11-25 [1] Github (r-lib/rprojroot@5bafca9) RSelenium 1.7.7 2020-02-03 [1] CRAN (R 3.6.1) semver 0.2.0 2017-01-06 [1] CRAN (R 3.6.0) sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0) stringi 1.5.3 2020-09-09 [1] CRAN (R 3.6.2) stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) wdman 0.2.5 2020-01-31 [1] CRAN (R 3.6.0) withr 2.3.0 2020-09-22 [1] CRAN (R 3.6.2) xfun 0.19 2020-10-30 [1] CRAN (R 3.6.2) XML 3.98-1.20 2019-06-06 [1] CRAN (R 3.6.0) xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.2) yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library ```


Created on 2021-01-04 by the reprex package (v0.3.0)

wch commented 3 years ago

Can you provide a simple version of the app that can just be copied and pasted? And preferably without RSelenium involved as well.

yonicd commented 3 years ago
options(shiny.trace = TRUE,shiny.launch.browser = .rs.invokeShinyWindowExternal)
shiny::runApp('inst/app')
global ```r this <- new.env() library(glue) library(stats) new_game <- function(rng = c(2,50), n = 25,signs = c('+','-','*','/')){ r <- sample(rng[1]:rng[2],2000,replace = TRUE) df <- r2df(r,n) sub_signs <- intersect(signs,c('+','-','*')) df$sign <- sample(sub_signs,n,replace = TRUE) if('/'%in%signs){ df$sign[df$x%%df$y==0] <- '/' } for(i in 1:nrow(df)){ df$m[i] <- eval( parse(text = glue::glue('{df$x[i]} {df$sign[i]} {df$y[i]}')) ) } df } r2df <- function(r,nn){ mat <- matrix(r,ncol = 2, byrow = FALSE) mat <- apply(mat,1,sort,decreasing = TRUE) mat <- t(mat) mat <- unique(mat[apply(mat,1,function(x) x[1]!=x[2]),]) nn <- min(nn,nrow(mat)) mat <- mat[sample(1:nrow(mat),nn),] mat_df <- as.data.frame(mat) names(mat_df) <- c('x','y') mat_df$row_id <- 1:nn mat_df$a <- 1 mat_df$z <- stats::runif(nn) v <- sample(1:2000,2*nn,replace = FALSE) mat_df$xx <- v[1:nn] mat_df$yy <- v[(nn+1):(2*nn)] mat_df } ```


server ```r app_server <- function( input, output, session ) { shiny::observeEvent(c(input$range,input$n,input$game,input$signs),{ shiny::req(input$range) shiny::req(input$n) shiny::req(input$signs) this$df <- new_game( rng = input$range, n = input$n, signs = input$signs ) this$counter <- 1 }) shiny::observeEvent( input$draw , { idx <- which(this$df$a==1) if(length(idx)==1){ s <- idx }else{ s <- sample(idx,1) } this$qp <- this$df[s,] output$ques <- shiny::renderText({ glue::glue('{this$qp$x} {this$qp$sign} {this$qp$y} ?') }) shiny::updateTextInput(session,'ans',value = '') r$draw <- input$draw }) # Store everything as a reactiveValues # that is passed to the module r <- shiny::reactiveValues( n = NULL, ans = "", draw = NULL, counter = 0, qp = NULL ) # Update the Values using the inputs shiny::observeEvent( input$game, { r$game <- input$game }) shiny::observeEvent( input$range, { r$range <- input$range r$counter <- r$counter + 1 session$sendCustomMessage('clickon','#game') }) shiny::observeEvent( input$signs, { r$counter <- r$counter + 1 session$sendCustomMessage('clickon','#game') }) shiny::observeEvent( input$n, { r$counter <- r$counter + 1 r$n <- input$n }) } ```


ui ```r ui <- shiny::tagList( shiny::fluidPage( htmltools::includeScript(path = "www/script.js"), shiny::checkboxGroupInput( inputId = "signs", label = "Choose Signs", inline = TRUE, choices = c('+','-','*','/'), selected = c('+','-','*','/') ), shiny::sliderInput(inputId = 'range', label = 'Number Range', min = 1, max = 100, value = c(1,10) ), shiny::sliderInput(inputId = 'n', label = 'Number of Questions', min = 4, max = 50,step = 1, value = 25 ), shiny::wellPanel( shiny::actionButton( inputId = 'game', label = 'New Game', onclick = "document.getElementById('draw').click()" ), shiny::actionButton('draw','New Question') ), shiny::verbatimTextOutput('ques'), shiny::wellPanel( id = 'anspanel', shiny::textInput( inputId = 'ans', label = NULL, value = '', placeholder = 'answer') ) ) ) ```


script.js ```js $( document ).ready(function() { Shiny.addCustomMessageHandler('clickon', function(what) { $(what).click(); }); }); ```


wch commented 3 years ago

That's better, but it should still be possible to remove significant amounts of code, and that will really help to zero in on the problem.

For example, it seems unlikely that the r2df() stuff is related to the reactivity issue, so it's best to take it out. And if it is related to the reactivity issue, that's important and interesting. I'd suggest removing bits of code until there's the minimum code that will reproduce the problem. See https://github.com/rstudio/shiny/wiki/Creating-a-Reproducible-Example for more.

You can create an app that has the reactlog stuff shown along with the app. See here for an example: https://github.com/rstudio/shinycoreci-apps/blob/c8a1bd4a318bd2a503f02a03abfc91bab5913335/apps/192-reactlog-hello/app.R

Additionally, you can inline the JS code with something like this in the UI:

tags$script(HTML("
$( document ).ready(function() {
  .....
});"
))

Ideally, someone else will be able to copy your code and paste it into a new R session to see the issue.

yonicd commented 3 years ago

I think i narrowed down where the problem is shiny::renderText, but i'm not sure why it is making a difference in gecko vs everything else.

options(shiny.trace=TRUE)

library(shiny)
library(reactlog)
reactlog_enable()
shiny::reactlogReset()

this <- new.env()

app_ui <- shiny::fluidPage(
  tags$script(HTML("
    $( document ).ready(function() {
      Shiny.addCustomMessageHandler('clickon', function(what) {
        $(what).click();
      });
    });"
  )),
  shiny::sidebarLayout(
    shiny::sidebarPanel(
      shiny::checkboxGroupInput(
        inputId = "signs", 
        label = "Choose Signs",
        inline = TRUE,
        choices = c('+','-','*','/'),
        selected = c('+','-','*','/')
    ),
    shiny::sliderInput(inputId = 'range', label = 'Number Range',
                       min = 1, max = 100, value = c(1,10)
    ),
    shiny::sliderInput(inputId = 'n', label = 'Number of Questions',
                       min = 4, max = 50,step = 1, value = 25
    ),
    shiny::wellPanel(
      shiny::actionButton(
        inputId = 'game',
        label = 'New Game',
        onclick  = "document.getElementById('draw').click()"
      ),
      shiny::actionButton('draw','New Question')
    ),
    shiny::verbatimTextOutput('ques'),
    shiny::wellPanel(
      id = 'anspanel',
      shiny::textInput(
        inputId = 'ans',
        label = NULL,
        value = '',
        placeholder = 'answer')
    )),
    shiny::mainPanel(
      reactlog_module_ui()
    )
  )
)

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

  shiny::observeEvent( input$range, {
    session$sendCustomMessage('clickon','#game')
  })

  shiny::observeEvent( input$signs, {
    session$sendCustomMessage('clickon','#game')
  })

  reactlog_module_server()

  shiny::observeEvent(c(input$range,input$n,input$game,input$signs),{

    shiny::req(input$range)
    shiny::req(input$n)
    shiny::req(input$signs)

    this$df <- data.frame(
      x = sample(input$range[1]:input$range[2],input$n,replace = TRUE),
      y = sample(input$range[1]:input$range[2],input$n,replace = TRUE),
      sign = sample(input$signs,1),
      a = 1,
      stringsAsFactors = FALSE
    )

  }) 
  shiny::observeEvent( input$draw , {

    idx <- which(this$df$a==1)

    if(length(idx)==1){
      s <- idx
    }else{
      s <- sample(idx,1)
    }

    this$qp <- this$df[s,]

    shiny::updateTextInput(session,'ans',value = '')

    ############################################
    # Commenting this out removes the behavior #
    ############################################

    output$ques <- shiny::renderText({
      sprintf('%s %s %s  ?',this$qp$x,this$qp$sign,this$qp$y)
    })

    ############################################
    # Commenting this out removes the behavior #
    ############################################

  })

}

shiny::shinyApp(
  ui = app_ui,
  server = app_server,
  options = list(launch.browser = shiny::browserViewer())
)
wch commented 3 years ago

Thanks, that version of the code is much easier to digest. Here's a version of it with even more stuff removed that does the same thing:

library(shiny)
library(reactlog)

options(shiny.trace=F)
reactlog_enable()
reactlogReset()

ui <- fluidPage(
  tags$script(HTML("
    $( document ).ready(function() {
      Shiny.addCustomMessageHandler('clickon', function(what) {
        console.log('customMessageHandler for clickon')
        $(what).click();
      });
    });"
  )),
  sidebarLayout(
    sidebarPanel(
      textInput("signs", "Signs:", value = "x"),
      textInput('range', 'Range:', value = "x"),
      actionButton('draw','Draw:'),
      verbatimTextOutput('ques')
    ),
    mainPanel(
      reactlog_module_ui()
    )
  )
)

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

  message("=============================")

  observeEvent( input$range, {
    message("==> input$range")
    session$sendCustomMessage('clickon','#draw')
  })

  observeEvent( input$signs, {
    message("==> input$signs")
    session$sendCustomMessage('clickon','#draw')
  })

  observeEvent( input$draw , {
    message("==> input$draw: ", input$draw)

    output$ques <- renderText({
      sprintf('output$ques text here')
    })
  })
}

shinyApp(ui, server, options = list(launch.browser = F, port = 5000))

Notably, in Chrome most of the time I see one instance of output$ques in the reactlog, but sometimes I see two instances of it. In Firefox, it looks like there are always two instances.

Here's a screenshot in Chrome with one output$ques: image

And another screenshot with two instances: image

But you can see the same thing without the reactlog. Each time the observeEvent expression is executed, it assigns a new object with output$ques <- renderText(...). In general, you want to avoid re-assigning something to an output unless there's a specific reason to do it. Typically, you do the assignment to output$ques outside of the observer.

Anyway, that part can be removed, and you can just look at the messages printed to the console. Sometimes I get this:

=============================
==> input$range
==> input$signs
==> input$draw: 2

And sometimes this:

=============================
==> input$range
==> input$signs
==> input$draw: 1
==> input$draw: 2

So the output$ques thing is sort of tangential to the actual issue. The real issue is that the observeEvent sometimes runs once, and sometimes twice.

The reason it's happening has to do with the way that sendCustomMessage works. For most Shiny output things, like render functions, all them execute, and then Shiny batches up the updates and sends them all in one message to the client.

sendCustomMessage is a bit different: the message is sent immediately, because we didn't want to impose any constraints on the timing of messages sent to the client.

The code always triggers two clicks, one from observeEvent(input$range), and one from observeEvent(input$signs). Because there are two observeEvents that call sendCustomMessage(), two separate messages are sent. Sometimes the browser receives and processes them very close in time, so that they occur in a single "tick" of the JS event loop. In that case, the browser just sends the value after two clicks, 2, to the server. When that happens, the observeEvent(input$draw, ...) executes just once.

However, if the browser is able to processes each message quickly enough that they occur in separate ticks of the JS event loop, then the browser first sends 1 to the server, and then 2. And when that happens, the observeEvent(input$draw, ...) executes twice.

The differences between Chrome and Firefox in your case are probably because Firefox is handling the messages more quickly. If you want to avoid this behavior, I suggest adding an observer that listens to both input$signs and input$range either directly, or indirectly.

yonicd commented 3 years ago

thanks for all the help and the thorough explanation!

yonicd commented 3 years ago

btw the inline messages you put in are exactly what {whereami} does.

In whereami's case it also logs the hits for you and keeps a record of what line was triggered in the source file.

For shiny it also reports which reactive chunk you are tracking.