The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

04 Advanced SpaDES use

Alex M. Chubaty

Eliot J. B. McIntire

May 20 2026

1 Advanced SpaDES use

This vignette covers tools that become useful once you are building or maintaining a substantial SpaDES workflow: monitoring memory use across events, and statically checking that a module’s code agrees with its declared metadata.

1.1 Memory monitoring

profvis::profvis is great for digging into R internals, but it doesn’t fit the discrete-event pattern very well. Often the question is simpler: which event uses the most memory, and how much? That number sets how many parallel runs you can fit on a machine.

SpaDES.core ships a small background sampler. Turn it on by setting the option spades.memoryUseInterval to a sampling interval in seconds (e.g., 0.2). If future and future.callr are installed, each spades() call will then:

  1. spawn a future (parallel) R session that runs system('ps') once per interval, keeping only the row for the main R process;
  2. write that to a text file;
  3. when spades() returns, read the file into sim@.xData$.memoryUse$obj and delete the file;
  4. [memoryUse()] joins that table to [completed()] by timestamp, so each event is annotated with its memory use.
if (requireNamespace("future", quietly = TRUE) &&
    requireNamespace("future.callr", quietly = TRUE)) {
  options(spades.memoryUseInterval = 0.5)

  # sim <- simInit(...)
  # sim <- spades(sim)

  memoryUse(sim, max = TRUE)  # peak memory by event type (summarised across times)
  memoryUse(sim, max = FALSE) # peak memory for every individual event
}

[memoryUseThisSession()] returns the memory currently used by the running R session; useful as a quick sanity check between events.

1.2 Static code checking

simInit() parses your module’s source and statically checks that the code agrees with the metadata: every read of sim$x should have x listed in expectsInput() or createsOutput(), every parameter access (Par$y, P(sim)$y, params(sim)$mod$y) should match a defineParameter() entry, every doEvent.* function should return sim, and so on. Mismatches are reported as a structured table with file/line/column locations.

The checks are controlled by two options:

options(spades.moduleCodeChecks = TRUE)    # turn checking on/off
options(spades.codeCheckEngine = "v2")     # "v1" (legacy) or "v2" (new, structured)

You can also run the checks on a module on disk, without going through simInit(). This is handy while authoring or refactoring a module:

# returns a data.frame of findings; also prints a grouped report
findings <- codeCheckModule("path/to/myModule")

# subset by severity or rule id
findings[findings$severity == "warning", ]
findings[findings$id == "param_used_undeclared", ]

A finding has columns id, severity, module, where, name, fn, file, line, col, message, suggestion. The suggestion is a plain-language fix (e.g., “add defineParameter('coverThresh', ...) to parameters”). When simInit() runs the checks, the same data.frame is stashed at sim@.xData$.codeCheck[[moduleName]].

Typical findings the checker flags:

id what it catches
out_declared_unused output declared in metadata, never assigned in code
out_used_undeclared sim$x <- ... for x not in createsOutput()
in_declared_unused input declared, never read
in_used_undeclared sim$x read for x not in expectsInput()
param_declared_unused defineParameter("x", ...) but no Par$x in the code
param_used_undeclared Par$x / P(sim)$x for x not declared
unresolved_accessor sim[[expr]] or get(var, envir=envir(sim)) — can’t be checked statically
must_return_sim doEvent.* not ending with return(invisible(sim))
must_assign_to_sim scheduleEvent(...) or saveFiles(...) not assigned back to sim
module_named_object sim$<moduleName> <- ... (forbidden)
conflicting_fn_unqualified bare levels/scale/which.max (ambiguous with raster::)

See [codeCheckModule()] for details.

2 References

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.