Life Cycle Management

The life cycle is a representation of the flow of execution states in a vivarium simulation. The tools in this model allow a simulation to formally represent its execution state and use the formal representation to enforce run-time contracts.

There are two flavors of contracts that this system enforces:

  • Constraints: These are contracts around when certain methods, particularly those available off the Builder, can be used. For example, simulants should only be added to the simulation during initial population creation and during the main simulation loop, otherwise services necessary for initializing that population’s attributes may not exist. By applying a constraint, we can provide very clear errors about what went wrong, rather than a deep and unintelligible stack trace.

  • Ordering Contracts: The SimulationContext will construct the formal representation of the life cycle during its initialization. Once generated, the context declares as it transitions between different lifecycle states and the tools here ensure that only valid transitions occur. These kinds of contracts are particularly useful during interactive usage, as they prevent users from, for example, running a simulation whose population has not been created.

The tools here also allow for introspection of the simulation life cycle.

exception vivarium.framework.lifecycle.LifeCycleError[source]

Generic error class for the life cycle management system.

exception vivarium.framework.lifecycle.InvalidTransitionError[source]

Error raised when life cycle ordering contracts are violated.

exception vivarium.framework.lifecycle.ConstraintError[source]

Error raised when life cycle constraint contracts are violated.

class vivarium.framework.lifecycle.LifeCycleState(name)[source]

A representation of a simulation run state.

Parameters:

name (str) –

property name: str

The name of the lifecycle state.

property entrance_count: int

The number of times this state has been entered.

add_next(next_state, loop=False)[source]

Link this state to the next state in the simulation life cycle.

States are linked together and used to ensure that the simulation life cycle proceeds in the proper order. A life cycle state can be bound to two next states to allow for loops in the life cycle and both are considered valid when checking for valid state transitions. The first represents the linear progression through the simulation, while the second represents a loop in the life cycle.

Parameters:
  • next_state (LifeCycleState) – The next state in the simulation life cycle.

  • loop (bool) – Whether the provided state is the linear next state or a loop back to a previous state in the life cycle.

valid_next_state(state)[source]

Check if the provided state is valid for a life cycle transition.

Parameters:

state (LifeCycleState | None) – The state to check.

Returns:

Whether the state is valid for a transition.

Return type:

bool

enter()[source]

Marks an entrance into this state.

add_handlers(handlers)[source]

Registers a set of functions that will be executed during the state.

The primary use case here is for introspection and reporting. For setting constraints, see LifeCycleInterface.add_constraint().

Parameters:

handlers (List[Callable]) – The set of functions that will be executed during this state.

class vivarium.framework.lifecycle.LifeCyclePhase(name, states, loop)[source]

A representation of a distinct lifecycle phase in the simulation.

A lifecycle phase is composed of one or more unique lifecycle states. There is exactly one state within the phase which serves as a valid exit point from the phase. The states may operate in a loop.

Parameters:
property name: str

The name of this life cycle phase.

property states: Tuple[LifeCycleState]

The states in this life cycle phase in order of execution.

add_next(phase)[source]

Link the provided phase as the next phase in the life cycle.

Parameters:

phase (LifeCyclePhase) –

get_state(state_name)[source]

Retrieve a life cycle state by name from the phase.

Parameters:

state_name (str) –

Return type:

LifeCycleState

class vivarium.framework.lifecycle.LifeCycle[source]

A concrete representation of the flow of simulation execution states.

add_phase(phase_name, states, loop)[source]

Add a new phase to the lifecycle.

Phases must be added in order.

Parameters:
  • phase_name (str) – The name of the phase to add. Phase names must be unique.

  • states (List[str]) – The list of names (in order) of the states that make up the life cycle phase. State names must be unique across the entire life cycle.

  • loop – Whether the life cycle phase states loop.

Raises:

LifeCycleError – If the phase or state names are non-unique.

get_state(state_name)[source]

Retrieve a life cycle state from the life cycle.

Parameters:

state_name (str) – The name of the state to retrieve

Returns:

The requested state.

Return type:

LifeCycleState

Raises:

LifeCycleError – If the requested state does not exist.

get_state_names(phase_name)[source]

Retrieve the names of all states in the provided phase.

Parameters:

phase_name (str) – The name of the phase to retrieve the state names from.

Returns:

The state names in the provided phase.

Return type:

List[str]

Raises:

LifeCycleError – If the phase does not exist in the life cycle.

class vivarium.framework.lifecycle.ConstraintMaker(lifecycle_manager)[source]

Factory for making state-based constraints on component methods.

check_valid_state(method, permitted_states)[source]

Ensures a component method is being called during an allowed state.

Parameters:
  • method (Callable) – The method the constraint is applied to.

  • permitted_states (List[str]) – The states in which the method is permitted to be called.

Raises:

ConstraintError – If the method is being called outside the permitted states.

constrain_normal_method(method, permitted_states)[source]

Only permit a method to be called during the provided states.

Constraints are applied by dynamically wrapping and binding a method to an existing component at run time.

Parameters:
  • method (Callable) – The method to constrain.

  • permitted_states (List[str]) – The life cycle states in which the method can be called.

Returns:

The constrained method.

Return type:

Callable

static to_guid(method)[source]

Convert a method on to a global id.

Because we dynamically rebind methods, the old ones will get garbage collected, making id() unreliable for checking if a method has been constrained before.

Parameters:

method (Callable) –

Return type:

str

class vivarium.framework.lifecycle.LifeCycleManager[source]

Manages ordering- and constraint-based contracts in the simulation.

property name: str

The name of this component.

property current_state: str

The name of the current life cycle state.

property timings: Dict[str, List[float]]
add_phase(phase_name, states, loop=False)[source]

Add a new phase to the lifecycle.

Phases must be added in order.

Parameters:
  • phase_name (str) – The name of the phase to add. Phase names must be unique.

  • states (List[str]) – The list of names (in order) of the states that make up the life cycle phase. State names must be unique across the entire life cycle.

  • loop (bool) – Whether the life cycle phase states loop.

Raises:

LifeCycleError – If the phase or state names are non-unique.

set_state(state)[source]

Sets the current life cycle state to the provided state.

Parameters:

state (str) – The name of the state to set.

Raises:
  • LifeCycleError – If the requested state doesn’t exist in the life cycle.

  • InvalidTransitionError – If setting the provided state represents an invalid life cycle transition.

get_state_names(phase)[source]

Gets all states in the phase in their order of execution.

Parameters:

phase (str) – The name of the phase to retrieve the states for.

Returns:

A list of state names in order of execution.

Return type:

List[str]

add_handlers(state_name, handlers)[source]

Registers a set of functions to be called during a life cycle state.

This method does not apply any constraints, rather it is used to build up an execution order for introspection.

Parameters:
  • state_name (str) – The name of the state to register the handlers for.

  • handlers (List[Callable]) – A list of functions that will execute during the state.

add_constraint(method, allow_during=(), restrict_during=())[source]

Constrains a function to be executable only during certain states.

Parameters:
  • method (Callable) – The method to add constraints to.

  • allow_during (List[str]) – An optional list of life cycle states in which the provided method is allowed to be called.

  • restrict_during (List[str]) – An optional list of life cycle states in which the provided method is restricted from being called.

Raises:
  • ValueError – If neither allow_during nor restrict_during are provided, or if both are provided.

  • LifeCycleError – If states provided as arguments are not in the life cycle.

  • ConstraintError – If a lifecycle constraint has already been applied to the provided method.

class vivarium.framework.lifecycle.LifeCycleInterface(manager)[source]

Interface to the life cycle management system.

The life cycle management system allows components to constrain methods so that they’re only available during certain simulation life cycle states.

Parameters:

manager (LifeCycleManager) –

add_handlers(state, handlers)[source]

Registers a set of functions to be called during a life cycle state.

This method does not apply any constraints, rather it is used to build up an execution order for introspection.

Parameters:
  • state (str) – The name of the state to register the handlers for.

  • handlers (List[Callable]) – A list of functions that will execute during the state.

add_constraint(method, allow_during=(), restrict_during=())[source]

Constrains a function to be executable only during certain states.

Parameters:
  • method (Callable) – The method to add constraints to.

  • allow_during (List[str]) – An optional list of life cycle states in which the provided method is allowed to be called.

  • restrict_during (List[str]) – An optional list of life cycle states in which the provided method is restricted from being called.

Raises:
  • ValueError – If neither allow_during nor restrict_during are provided, or if both are provided.

  • LifeCycleError – If states provided as arguments are not in the life cycle.

  • ConstraintError – If a life cycle constraint has already been applied to the provided method.

current_state()[source]

Returns a callable that gets the current simulation lifecycle state.

Returns:

A callable that returns the current simulation lifecycle state.

Return type:

Callable[[], str]