You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When an asynchronous function created with coro::async is used as a method of an R6 class, the function fails with an error indicating that the internal _parent object is missing. It appears that R6’s practice of replacing a method’s environment (to provide self/private) is stripping out the closure variable _parent that the async machinery relies on. This issue is similar in spirit to #30 (which dealt with generators), but now it affects async functions as well.
Minimal Reproducible Example:
#!/usr/bin/env Rscript
options(error=function() {
rlang::entrace()
rlang::last_trace()
})
sessionInfo()
print(paste("coro: ", packageVersion("coro")))
print(paste("promises: ", packageVersion("promises")))
print(paste("later: ", packageVersion("later")))
print(paste("rlang: ", packageVersion("rlang")))
print(paste("R6: ", packageVersion("R6")))
api_data<-function() {
return(promises::promise(function(resolve, reject) {
later::later(function() {
resolve("Hello, API!")
}, delay=3)
}))
}
MyAPI<-R6::R6Class("MyAPI",
public=list(
getData=coro::async(function() {
message("Simulating API call...")
result<- await(api_data())
return(result)
})
)
)
# Create an instance and call the asynchronous method.api<-MyAPI$new()
api$getData()$
then(function(data) {
message("Data received: ", data)
})$
catch(function(e) {
message("Error: ", conditionMessage(e))
})
# Run the later event loop until all asynchronous tasks are complete.while (!later::loop_empty()) {
later::run_now()
}
(base) work@Derecks-MacBook-Air kucoin % Rscript research/r6-coro-async.R
R version 4.4.1 (2024-06-14)
Platform: aarch64-apple-darwin23.4.0
Running under: macOS 15.3
Matrix products: default
BLAS: /opt/homebrew/Cellar/openblas/0.3.27/lib/libopenblasp-r0.3.27.dylib
LAPACK: /opt/homebrew/Cellar/r/4.4.1/lib/R/lib/libRlapack.dylib; LAPACK version 3.12.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: America/Chicago
tzcode source: internal
attached base packages:
[1] stats graphics grDevices datasets utils methods base
loaded via a namespace (and not attached):
[1] compiler_4.4.1 tools_4.4.1 renv_1.0.7
[1] "coro: 1.1.0"
[1] "promises: 1.3.0"
[1] "later: 1.3.2"
[1] "rlang: 1.1.4"
[1] "R6: 2.5.1"
Error in api$getData() : object '_parent' not found
Calls: <Anonymous> -> <Anonymous> -> dots_split
Backtrace:
▆
1. ├─api$getData()
2. │ └─rlang::env(`_parent`)
3. │ └─rlang:::dots_split(..., .n_unnamed = 0:1)
4. └─global `<fn>`()
Execution halted
(base) work@Derecks-MacBook-Air kucoin %
My understanding
The problem seems to stem from how coro::async captures its internal _parent environment. When the async function is defined, _parent is available in the closure. However, R6 replaces method environments with its own class environment during instantiation (to provide self and private), and in doing so, it loses the _parent binding that coro::async relies on. Thus, when the async function is later invoked, a call to rlang::env("_parent") fails because _parent is not found.
I would be happy to work on a pull request to implement a change/bug fix. Any guidance is appreciated.
The text was updated successfully, but these errors were encountered:
When an asynchronous function created with
coro::async
is used as a method of an R6 class, the function fails with an error indicating that the internal_parent
object is missing. It appears that R6’s practice of replacing a method’s environment (to provideself
/private
) is stripping out the closure variable_parent
that the async machinery relies on. This issue is similar in spirit to #30 (which dealt with generators), but now it affects async functions as well.Minimal Reproducible Example:
My understanding
The problem seems to stem from how
coro::async
captures its internal_parent
environment. When the async function is defined,_parent
is available in the closure. However, R6 replaces method environments with its own class environment during instantiation (to provideself
andprivate
), and in doing so, it loses the_parent
binding thatcoro::async
relies on. Thus, when the async function is later invoked, a call torlang::env("_parent")
fails because_parent
is not found.I would be happy to work on a pull request to implement a change/bug fix. Any guidance is appreciated.
The text was updated successfully, but these errors were encountered: