Skip to content

Commit 6956881

Browse files
billdenneyclaude
andcommitted
fix: unique-per-call probe file in copy_article_images()
When two or more workers render articles from the same source directory in parallel, the fixed filename <path_dir(input_path)>/--find-assets.html written by copy_article_images() collides between workers, surfacing as [EEXIST] Failed to copy '<built>.html' to '<src>/--find-assets.html': file already exists [ENOENT] Failed to remove '<src>/--find-assets.html': no such file or directory depending on whether the failing worker raced on the file_copy or on its sibling's deferred file_delete. The race is observable with as few as two workers and bites reliably at >= 6 workers on a 400- vignette package (see nlmixr2/nlmixr2lib PR #427, run 26225121646). The probe file has to live next to the input Rmd so the relative paths in the built HTML resolve when rmarkdown::find_external_resources reads them back; tempdir() would break that. Generate a unique filename per call via tempfile(pattern = "--find-assets-", tmpdir = path_dir(input_path), fileext = ".html") so concurrent workers in the same source directory each get their own probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 001e6f5 commit 6956881

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
* `build_articles()`, `build_site()`, and `build_site_github_pages()` gain an `n_cores` argument to build articles in parallel via `purrr::in_parallel()`. The default (`n_cores = 1L`) preserves the traditional serial build; values greater than 1 require the mirai package, and `Inf` autodetects via `parallel::detectCores()`.
44

5+
* The internal `copy_article_images()` helper no longer races on a fixed `--find-assets.html` probe file when articles in the same source directory are built in parallel; the probe filename is now made unique per call via `tempfile()`.
6+
57
* When previewing a site, it is now served via a local http server. This enables dynamic features such as search to work correctly (@shikokuchuo, #2975).
68

79
* do not autolink code that is in a link (href) in Rd files (#2972)

R/build-article.R

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,18 @@ copy_article_images <- function(built_path, input_path, output_path) {
260260
ext_src <- rmarkdown::find_external_resources(input_path)
261261

262262
# temporarily copy the rendered html into the input path directory and scan
263-
# again for additional external resources that may be been included by R code
264-
tempfile <- path(path_dir(input_path), "--find-assets.html")
265-
withr::defer(try(file_delete(tempfile)))
266-
file_copy(built_path, tempfile)
267-
ext_post <- rmarkdown::find_external_resources(tempfile)
263+
# again for additional external resources that may be been included by R code.
264+
# The probe file has to live next to the input Rmd so relative paths in the
265+
# HTML resolve correctly; use tempfile() so concurrent workers in the same
266+
# source directory don't race on a fixed filename.
267+
probe_file <- tempfile(
268+
pattern = "--find-assets-",
269+
tmpdir = path_dir(input_path),
270+
fileext = ".html"
271+
)
272+
withr::defer(try(file_delete(probe_file)))
273+
file_copy(built_path, probe_file)
274+
ext_post <- rmarkdown::find_external_resources(probe_file)
268275

269276
ext <- rbind(ext_src, ext_post)
270277
ext <- ext[!duplicated(ext$path), ]

0 commit comments

Comments
 (0)