This chapter attempts to document the order of important operations done during environment transitions. Since AliECS is an evolving system, the information presented here might be out-of-date, thus please refer to event handling in environment.go and plugin calls in ControlWorkflows/workflows/readout-dataflow.yaml for the ultimate source of truth. Also, please report to the ECS developers any inaccuracies.
The underlying state machine library allows us to add callbacks upon entering and leaving states as well as before and after events (transitions). This is the order of callback execution upon a state transition:
before_<EVENT>- called before event named<EVENT>before_event- called before all eventsleave_<OLD_STATE>- called before leaving<OLD_STATE>leave_state- called before leaving all statesenter_<NEW_STATE>,<NEW_STATE>- called after entering<NEW_STATE>enter_state- called after entering all statesafter_<EVENT>,<EVENT>- called after event named<EVENT>after_event- called after all events
Callback execution is further refined with integer indexes, with the syntax ±index, e.g. before_CONFIGURE+2, enter_CONFIGURED-666.
An expression with no index is assumed to be indexed +0. These indexes do not correspond to timestamps, they are discrete labels that allow more granularity in callbacks, ensuring a strict ordering of callback opportunities within a given callback moment.
Thus, before_CONFIGURE+2 will complete execution strictly after before_CONFIGURE runs, but strictly before enter_CONFIGURED-666 is executed.
Following States and Transitions are represented by this diagram:
This is the order of actions happening at a healthy start of run.
before_START_ACTIVITYhooks with negative weights are executed:trg.PrepareForRun()at-200lhc.UpdateFillInfo()at-50
"run_number"is set."run_start_time_ms"is set using the current time. It is considered as the SOR and SOSOR timestamps.before_START_ACTIVITYhooks with positive weights (incl. 0) are executed:trg.RunLoad(),bookkeeping.StartOfRun()at10kafka.PublishStartActivityUpdate()at50dcs.StartOfRun(),odc.Start()(does not need to return now),ccdb.RunStart()at100
leave_CONFIGUREDhooks are executed:kafka.PublishLeaveStateUpdate()at0
- Fill Info previously retrieved by the BKP plugin is read from the variable stack and put into transition message to tasks
- Tasks are transitioned to
RUNNING - If everything succeeds up to this point, we report that the run has started
enter_RUNNINGhooks are executedo2-roc-ctp-emulatorfor all ROC CTP emulator endpoints,kafka.PublishEnterStateUpdate()at0
after_START_ACTIVITYhooks with negative weights are executedtrg.RunStart()at-10- waiting until
odc.Start()executed atbefore_START_ACTIVITY+100completes at-10
"run_start_completion_time_ms"is set using current time. It is considered as the EOSOR timestamp.after_START_ACTIVITYhooks with positive weights (incl. 0) are executed:bookkeeping.UpdateRunStart(),bookkeeping.UpdateEnv()at+100
This is the order of actions happening at a healthy end of run.
before_STOP_ACTIVITYhooks with negative weights are executedlhc.UpdateFillInfo()at-50trg.RunStop()at-10
"run_end_time_ms"is set using the current time. It is considered as the EOR and SOEOR timestamps.before_STOP_ACTIVITYhooks with positive weights (incl. 0) are executed:odc.Stop()(does not need to return now) at0
leave_RUNNINGhooks are executedkafka.PublishLeaveStateUpdate()at0
- Tasks are transitioned to
CONFIGURED - If everything succeeds up to this point, we consider that the run has stopped
enter_CONFIGUREDhooks are executedkafka.PublishEnterStateUpdate()at0
after_STOP_ACTIVITYhooks with negative weights are executed:trg.RunUnload()at-100dcs.EndOfRun()at-50- waiting until
odc.Stop()executed atbefore_STOP_ACTIVITYcompletes at-50
"run_end_completion_time_ms"is set using current time. It is considered as the EOEOR timestamp.after_STOP_ACTIVITYhooks with positive weights (incl. 0) are executed:ccdb.RunStop()at0bookkeeping.UpdateRunStop(),bookkeeping.UpdateEnv()at+100
State PENDING and transitions TEARDOWN, and DESTROY lie outside the core FSM in environment.go and are driven by the Manager. See core/environment/manager.go for details.
As these are not in a FSM we trigger them be calling specific methods. You can find details about triggering these in the according sections.
Before the FSM enters STANDBY, the Manager drives the initial creation steps by emitting Ev_EnvironmentEvent messages (Transition: CREATE, State: PENDING) for both before_CREATE (running hooks) and CREATE (loading workflow).
When the FSM is in RUNNING and TeardownEnvironment function is called, the Manager records both run_end_time_ms and run_end_completion_time_ms and emits message Ev_RunEvent with content (Transition: TEARDOWN, OpStatus_STARTED) for each of timestamps. Right now there is only OpStatus_STARTED reported in Kafka. You can trigger TeardownEnvironment for example by invoking gRPC method DestroyEnvironment with Force = true. You cannot trigger TEARDOWN by calling gRPC method Teardown.
The Manager’s TeardownEnvironment(...) drives a four‑step Ev_EnvironmentEvent sequence (before_DESTROY, leave_<state>, DESTROY, after_DESTROY) on topic.Environment to release tasks, run hooks, and finalize teardown.
You can trigger TeardownEnvironment for example by invoking gRPC method DestroyEnvironment with Force = true.