The modification_tracker
is responsible for determining whether
any changes have been made to the file(s) associated to the given
resource.
modification_tracker(object, ..., modification_tracker.return = "object", modification_tracker.touch = TRUE)
object | active_resource. See |
---|---|
... | additional parameters to pass to the next layer in the resource parsing tower. |
modification_tracker.return | character. What to return in this layer
of the parsing tower. The options are The former returns whether or not the file associated with the resource has been modified (or in the case of idempotent resources, the file and its helpers). The resource itself will not be parsed. The latter, |
modification_tracker.touch | logical. Whether or not to update an
internal cache that keeps track of last time the resource is modified.
This is an internal parameter that is set to |
The parsed resource.
If a modification has been detected, the local modified
will be injected for use in the preprocessor or parser for the resource.
Note that we can use the modification_tracker
to determine
whether the resource has been modified:
director_object$resource(resource_name,
modification_tracker.touch = FALSE,
modification_tracker.return = "modified")
The use of modification_tracker.touch = FALSE
is necessary to avoid
polluting the internal cache that determines whether or not the resource
has been modified.
The parameters must be named object
and ...
due to
this method's inclusion in a tower
.
active_resource
, tower
not_run({ # Imagine we are constructing a stagerunner from a sequence of functions. # However, some of those functions have been built by other resources. # Imagine the following structure. # (See github.com/robertzk/stagerunner for an explanation of stagerunners.) #=== /dir/runners/project1.R === list( "import data" = resource("importers/db"), # These are some functions "munge data" = resource("mungers/impute"), # built by the user "create model" = resource("models/lm"), # that live in other "export model" = resource("exporters/file") # files. ) #=== R console === d <- director("/dir") # Create a director object. d$register_preprocessor("runners/", function(director, source, modified) { # `modified` has been set by the modification_tracker to # TRUE or FALSE according as /dir/runners/project1.R has been modified. if (modified || is.null(runner <- director$cache_get("last_runner"))) { # Construct a new stageRunner, since the file has been modified. source() } else { runner } }) d$register_parser("runners/", function(output) { # If it is a stageRunner, it must have been retrieved from the cache. if (stagerunner::is.stageRunner(output)) { return(output) } runner <- stagerunner::stageRunner$new(new.env(), output) # Cache the runner so it is available in the preprocessor next time. # As long as the /dir/runners/project1.R file remains untouched, we will # not have to bother re-sourcing the file and hence reconstructing the # stageRunner. director$cache_set("last_runner", runner) runner }) sr <- d$resource("runners/project1") # A fresh new stageRunner! sr2 <- d$resource("runners/project1") # Same one, since it used the cache. stopifnot(identical(sr, sr2)) # We can use base::Sys.setFileTime to pretend like we updated the # modified time of the project1.R file, triggering `modified = TRUE`. Sys.setFileTime(file.path(d$root(), "runners", "project1.R"), Sys.time() - as.difftime(1, units = "mins")) sr3 <- d$resource("runners/project1") # Now it re-builds the runner. stopifnot(!identical(sr, sr3)) # A new runner! })