-
-
Notifications
You must be signed in to change notification settings - Fork 977
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
Shiny prerendered dependencies are sometimes written twice into prerendered HTML #2499
Comments
I have a suspicion that there are somehow two processes running at the same time to prerender the source document and are inadvertently writing into the same file. I've uncovered a reproducible example that produces the expected error (here shown before the fix in #2500). render_bg <- function(path) {
callr::r_bg(
function(path) {
rmarkdown::render(path)
},
args = list(path = path)
)
}
# Remove prerendered HTML and source if they exist
unlink("issue.html")
unlink("issue.Rmd")
writeLines('---
title: "issue"
output: html_document
runtime: shiny_prerendered
---
```{r}
textInput("text", "Text", "Text")
renderText(input$text)
```', "issue.Rmd"
)
# Render the Rmd twice at basically the same time
r1 <- render_bg("issue.Rmd")
r2 <- render_bg("issue.Rmd")
r2$wait() When you try to run the document, it will have been corrupted by simultaneous writes into the rmarkdown::run("issue.Rmd")
#> Error: parse error: trailing garbage
#> ":{},"value":["2.23.3"]}]}]} {"type":"list","attributes":{},
#> (right here) ------^ After applying the fix in #2500, we still get errors due to failures in other places in the file. rmarkdown::run("issue.Rmd")
#> Error: lexical error: invalid char in json text.
#> s":{},"value":["jquerylib"]} <!--html_preserve--> {"type":"l
#> (right here) ------^ |
Good find ! I don't know if we should do something about this in rmarkdown (at least as a bug fix). I don't think we do anything against this not even for This is the responsability to who or what is calling Related issue on that concurrency topic:
|
In this case, my reprex is a hypothetical example that's at least consistent with the real-world scenario. I've heard reports of this kind of problem for learnr users on Connect and shinyapps.io as well as Posit Cloud. Cloud is surprising to me because in theory it should be equivalent to a local installation, where this problem hasn't been reported really. Related to the concurrency option, I understand that there are many reasons that make writing unique files difficult. That said, if we're using a mechanism like |
Yes makes sense |
This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary. |
learnr has long-suffered from a hard-to-replicate bug that results in an error like this:
I've finally tracked down the core mechanism, but I don't know the root cause. When a shinyrmd document is pre-rendered into HTML, it writes the dependencies used in the app into the prerendered HTML so that it can be used at runtime:
rmarkdown/R/render.R
Lines 857 to 862 in 1d739bd
shiny_prerendered_append_dependencies()
writes two JSON-serialized objects into<script>
tags withdata-context
attributes"dependencies"
and"execution_dependencies"
.rmarkdown/R/shiny_prerendered.R
Lines 370 to 380 in 1d739bd
In rstudio/learnr#597 (comment) I was sent copies of tutorial files that exhibited this behavior, and they contain duplicated dependency chunks. Importantly, the entire group of dependencies + execution dependencies are duplicated, rather than each one being written twice in place. Here's roughly what the prerendered html looks like:
When starting up the app,
shiny_prerendered_html()
extracts the"dependencies"
and"execution_dependencies"
contextsrmarkdown/R/shiny_prerendered.R
Lines 157 to 159 in 1d739bd
but strongly assumes that there is exactly a single string returned by
shiny_prerendered_extract_context()
when it passes the extracted context tojsonlite::unserializedJSON()
, which does not like the invalid JSON.I'd like to know why
shiny_prerendered_append_dependencies()
is called twice during pre-render, but I also think we can reasonably avoid this issue by checking the"dependencies"
context contents before handing them tounserializedJSON()
. I'll submit a PR with this change shortly.The text was updated successfully, but these errors were encountered: