public abstract class ModelInitialiser
extends java.lang.Object
We want to separate logs for each run in multi-run experiments and use the standard way to do this in Logback: use sifting appenders which dynamically create per-run appenders based on an SLF4J MDC key-value pair, where this pair is unique per thread (with the value inherited by child threads). See:
Because visualised versions of the model may embed (or extend) unvisualised versions (which can also run standalone), they share a ModelInitialiser instance (created by the parent or superclass MainModel). It is expected that both (as MainModel instances) will want to get the shared instance of this class (see the static factory method).
Typically, single model runs exist in a single thread, and batch runs
launch a thread per run therein. However, we have to allow for
(a) runs in a non-parallel multi-run experiment (or single-run ones which can be stopped/
re-run from scratch) being done in the same thread;
(b) models changing thread during their run.
(For example, AnyLogic does both of these: (b) when a model is paused and resumed.)
Thus
We handle all this by storing the key values that we set (in the constructor) so that we can compare to these and, in case (b), reapply the MDC keys from the stored values. These keys include one (INIT_MAIN_MODEL_KEY) which is the class name of the MainModel subclass which triggered the instantiation; if this exists and *isn't* the main model class name calling the factory method, we know that a parent already instantiated it and we return that (from our static Hashtable). In case (a) above, we would have the class name of the main model attempting the instantiation.
For case (b), this can only be detected by the (framework-specific) experiment running the model. We provide a method to reapply the stored MDC key values to the new thread, which code in the experiment needs to call at the appropriate time.
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
EVENT_LOGGER_NAME
'Domain events' (from event managers) go to this single uniquely-named logger.
|
static java.lang.String |
SETTINGS_FILE
Name for the model run settings file produced.
|
static java.lang.String |
STOCH_CONTROL_FILE
Name for the input stochasticity control file.
|
Constructor and Description |
---|
ModelInitialiser(java.lang.String experimentName,
MainModel modelMain,
boolean slf4jBoundToLogback)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
static void |
debugThreadInfo(org.slf4j.Logger logger)
Using the Logger provided, produce a debug message showing the current thread
and the run ID stored via MDCs.
|
void |
disableStochOverrides()
Disable stochastic overrides (as provided by the stochasticity control file).
|
void |
finaliseStochRegistrations()
Call this when sure that no further stochastic items will be registered, which then
allows the per-run settings file to be produced.
|
java.lang.String |
getElapsedTimeSecs()
Get elapsed model processing time in seconds.
|
static ModelInitialiser |
getExistingInitialiser(MainModel modelMain)
Exposed for technical reasons; not intended for JSIT user use.
|
static int |
getJRE_MajorVersionNumber()
Utility method to get the current JRE major version number.
|
ch.qos.logback.classic.LoggerContext |
getLogbackContext()
Get the Logback context for this model.
|
java.lang.String |
getOutputFilesBasePath()
Get the base path for this run's output files.
|
java.lang.String |
getRunID()
Get the JSIT-derived run ID (as used in output folder names).
|
boolean |
isModelInitiator(MainModel modelMain)
Determine whether a main model is the model initialiser or not (since a model
may have multiple MainModel instances and only one initiates the JSIT environment,
typically the first instantiated).
|
void |
onMainModelDestroy()
Call this when the MainModel is destroyed to clean up statically-held storage for the run.
|
void |
possibleMDC_KeysLoss()
Primarily used internally (and exposed for technical reasons) to restore MDC
key values used to associate an active thread with a model run (needed for AnyLogic
models due to threading issues).
|
Sampler |
registerStochItem(AbstractStochasticItem stochItem)
Method exposed for technical reasons; not intended for JSIT user use.
|
void |
saveModelSettings()
Save model settings to a file in the output folder.
|
public static final java.lang.String SETTINGS_FILE
public static final java.lang.String STOCH_CONTROL_FILE
public static final java.lang.String EVENT_LOGGER_NAME
public ModelInitialiser(java.lang.String experimentName, MainModel modelMain, boolean slf4jBoundToLogback)
experimentName
- A string defining the experiment (set of related runs) this
model instance is part of. (Used to derive the JSIT run ID.)modelMain
- The MainModel instance that is the 'root' object for the
model.slf4jBoundToLogback
- Whether SLF4J is bound to Logback or not. (If not, we need to
explicitly initialise Logback ourselves; see later comments.)public static void debugThreadInfo(org.slf4j.Logger logger)
logger
- The Logger to use to log the message. (This must be set to log
DEBUG level messages for the message actually be produced.)public static ModelInitialiser getExistingInitialiser(MainModel modelMain)
modelMain
- The MainModel instance that is checking for an existing initialiser.public static int getJRE_MajorVersionNumber()
public void possibleMDC_KeysLoss()
JSIT users may want to call this themselves if there are instances where their model can switch threads for a run (to one that is not a child of the previous one).
public boolean isModelInitiator(MainModel modelMain)
This is primarily used internally (and exposed for technical reasons).
modelMain
- The MainModel interface to check.public java.lang.String getElapsedTimeSecs()
public java.lang.String getRunID()
public java.lang.String getOutputFilesBasePath()
public ch.qos.logback.classic.LoggerContext getLogbackContext()
public void saveModelSettings() throws java.io.IOException
JSIT users will only need to call this manually if not using a helper library.
java.io.IOException
- if there are problems creating/writing the output file.public void finaliseStochRegistrations()
This will be called as part of the main model destroy processing (onMainModelDestroy method) if the user does not call it earlier.
public void onMainModelDestroy()
public Sampler registerStochItem(AbstractStochasticItem stochItem)
Register a dist or lookup, which involves setting its sample mode and checking for double registrations. Returns the sampler so that the caller (a stoch accessor) can register itself and the sampler in the stoch item.
stochItem
- The stochastic item to register.public void disableStochOverrides()