Lifecycle Logic
AQE exposes one trait per lifecycle phase:
pub trait OnStartLogic { fn version(&self) -> &str; fn run(&mut self, ctx: &mut dyn StrategyContext) -> LifecycleResult;}
pub trait OnInitLogic { fn version(&self) -> &str; fn run(&mut self, ctx: &mut dyn StrategyContext, asset: &Asset) -> LifecycleResult;}
pub trait OnTeardownLogic { fn version(&self) -> &str; fn run(&mut self, ctx: &mut dyn StrategyContext) -> LifecycleResult;}Each run method returns LifecycleResult, which records success, an optional message, and component metadata. A failed component with can_fail(false) stops the run; a failed component with can_fail(true) logs the failure and lets the run continue.
Default failure policy:
OnStartLogic: strict by defaultOnInitLogic: strict by defaultOnTeardownLogic: tolerant by default, because cleanup should continue where possible
Timing
Section titled “Timing”Lifecycle wrappers use LifecycleTiming to choose where they run around the strategy method body:
LifecycleTiming::BeforeGeneratedLifecycleTiming::AfterGeneratedIn generated AQS projects, “generated” means the method body generated from the graph. In hand-written AQE projects, it is the inline body you wrote in the Strategy implementation.
Use BeforeGenerated for validation, environment setup, state seeding, and dependencies that the strategy body expects. Use AfterGenerated for follow-up work, registration checks, and metadata that depends on the strategy body having run.
Registering Lifecycle Logic
Section titled “Registering Lifecycle Logic”Direct AQE projects register lifecycle logic on StrategyState before starting the run. The engine calls the components automatically; user strategy code should not call lifecycle run helpers manually.
state.add_on_start_logic( OnStartLogicBuilder::new(Box::new(SeedRuntimeState::new())) .timing(LifecycleTiming::BeforeGenerated) .can_fail(false) .build(),);
state.add_on_init_logic( OnInitLogicBuilder::new(Box::new(InitAssetState::new())) .timing(LifecycleTiming::AfterGenerated) .can_fail(false) .build(),);
state.add_on_teardown_logic( OnTeardownLogicBuilder::new(Box::new(FlushRuntimeLogs::new())) .timing(LifecycleTiming::AfterGenerated) .can_fail(true) .build(),);Example On-Start Component
Section titled “Example On-Start Component”use aq_engine::core::lifecycle::{LifecycleResult, OnStartLogic};use aq_engine::core::strategy::StrategyContext;use serde_json::json;
pub struct SeedRuntimeState;
impl SeedRuntimeState { pub fn new() -> Self { Self }}
impl OnStartLogic for SeedRuntimeState { fn version(&self) -> &str { "1.0" }
fn run(&mut self, ctx: &mut dyn StrategyContext) -> LifecycleResult { ctx.variables().insert( self.name().to_string(), json!({ "started": true, "symbols_seen": 0 }), );
LifecycleResult::passed(self.name().to_string()) }}We use essential cookies and storage for sign-in, account security, colour theme preferences, this notice, and required PostHog internal usage, session quality, and reliability metrics. We do not use advertising cookies.
