Imported from r-lib/later (
AGENTS.md). Install upstream withnpx skills add r-lib/later. Copyright stays with the author.
AGENTS.md
Project overview
later is an R package that schedules R or C functions to run after a delay,
via an event loop. It is the foundation of async programming in R (used by
promises, httpuv, shiny). Scheduled callbacks only run when the R
execution stack has emptied (at the top-level prompt), or when run_now() is
called — this avoids reentrancy bugs.
- Repo: https://github.com/r-lib/later
- License: MIT
- R >= 3.5; Imports: Rcpp, rlang; native code in
src/(C++ and C)
Repository layout
R/— R code.later.Rhas the main API (later(),run_now(),later_fd(), private event loops:create_loop(),with_loop(),global_loop(), etc.).RcppExports.Ris auto-generated — do not edit.src/— native implementation:later.cpp— core scheduling logic;later.hlater_posix.cpp/later_win32.cpp— platform event loopscallback_registry.{h,cpp}— callback storage and invocationtimer_posix.*,timestamp_{unix,win32}.*,fd.*— platform supporttinycthread.c/h— vendored threading library (see "Gotchas")wref.c— weak references;init.c— native routine registrationRcppExports.cpp— auto-generated — do not editMakevars.in→Makevarsis generated byconfigure(gitignored); editMakevars.in/Makevars.win, neverMakevars
include/later_api.h— public C/C++ API consumed by downstream packages (e.g. httpuv). ABI compatibility matters; changes here affect other packages.tests/testthat/— testthat (3rd edition).test-c-api.Rcompiles C++ againstlater_api.h(helper ininst/promise_task.cpp).man/— generated by roxygen2; do not edit.docs/— pkgdown output.README.mdis generated fromREADME.Rmd— edit the.Rmd.
Common tasks
devtools::load_all() # compile native code + load
devtools::test() # run testthat suite
devtools::document() # regenerate man/, NAMESPACE, RcppExports
devtools::check() # full R CMD check
- Format R code with Air:
air format .(config inair.toml). - After changing roxygen comments, run
devtools::document()before checking. - Reverse dependencies live in
revdep/;cran-comments.mdtracks CRAN submissions.
Conventions and gotchas
- Threading: threads come from the vendored tinycthread, whose exported
symbols are renamed with a
tct_prefix to avoid clashing with system C11<threads.h>symbols at link time.src/badthreads.hdeliberately poisons all C11 threads.h names so they fail at compile time. Do not include<threads.h>or usethread_local(a C23 keyword). Seesrc/README.md. - C++ exceptions in callbacks: downstream packages schedule native
callbacks whose bodies are C++ and may throw. These must be caught at the
invocation leaf (see
callback_registry.h) and converted to R errors — letting an exception unwind into a C frame is UB and crashes R (issues #191, #241). Preserve this behavior. - Weak refs are implemented in C (
src/wref.c) rather than via rlang so that loadinglaterdoes not pull in rlang — keep it that way (overhead matters for packages that only link tolater). configuredetects whether-latomicis needed (some ARM platforms) and generatessrc/Makevars;cleanupremoves it.- Event loop semantics: callbacks run only when no R code is on the
execution stack. Private loops with
parent = NULLrun only via explicitrun_now(). Be careful with anything that changes when/where callbacks execute. - roxygen2 with markdown is enabled; testthat edition 3.