-
-
Notifications
You must be signed in to change notification settings - Fork 42
Description
I have a contrived example below to illustrate the issue. If you override log_ to make debug output tunable, you can end up with a situation where you get a surprising error--"Error: add_generator: 'trajectory' is not a valid trajectory." After troubleshooting for too long, it became clear what was happening--a trajectory must have a single action and, as a result, adding an artificial timeout(0) creates a valid trajectory. How did I run into this in practice? I had a branch in my trajectory where one of the outcomes was a single log_ call showing the condition that had occurred.
Thoughts (unordered) on what to do:
- Update an appropriate vignette that shows this override mechanism and how to workaround the 1 action with debugging converts to 0 actions without issue.
- Add a call(.trj,,...) mechanism with a callback mechanism that would allow someone to have a valid action. Beyond allowing someone to override log, it would also be a natural place for the case where someone calls timeout() with a callback that updates some internal state and always returns 0.
- Similar to the syslog interface, add an optional modifier to log_ to allow for levels of debugging.
- Add a hack to log_ where a function returning an empty string transparently prints nothing. I dislike this one enough that I almost didn't write it down but it is a defensible option.
There might also be an option with inheritance but I've never used R's OO capabilities so it's not clear to me if that's a potential method (pun intended) as well.
library(simmer)
t1 <- function(log=log_,work=TRUE) {
t <- trajectory() %>% log(paste("T1","starting"))
if(work)
t %>% timeout(0)
t
}
t2 <- function(log=log_,work=TRUE) {
t <- trajectory() %>% log(paste("T2","starting"))
if(work)
t %>% timeout(0)
t
}
runmerge <- function(log=log_,work=TRUE) {
env <- simmer() %>% add_generator("T1",t1(log,work),at(0)) %>%
add_generator("T2",t2(log,work),at(0)) %>%
run() %>% invisible
}
runmerge_quiet_works <- function () runmerge(function(.trj,message) .trj)
runmerge_quiet <- function () runmerge(function(.trj,message) .trj,FALSE)
print('Runmerge with output')
runmerge()
print('Runmerge without output and a timeout of 0 to please validation')
runmerge_quiet_works()
print('Runmerge without output and no timeout')
runmerge_quiet()