Skip to content

Allow zero-action trajectories to be valid. #150

@mtbakerguy

Description

@mtbakerguy

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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions