Skip to main content

LifecycleHooks

Trait LifecycleHooks 

Source
pub trait LifecycleHooks:
    Send
    + Sync
    + 'static {
    // Provided methods
    fn observe(&self, _event: &LifecycleEvent<'_>) -> Result<(), AppError> { ... }
    fn observe_async<'a>(
        &'a self,
        _event: &'a LifecycleEvent<'a>,
    ) -> impl Future<Output = Result<(), AppError>> + Send + 'a { ... }
}
Expand description

Caller-owned lifecycle observation without a transport or exporter owner.

Both methods default to success. Asynchronous execution calls the synchronous method before the asynchronous method; synchronous execution calls only the synchronous method. Events borrow their authoritative data for the duration of the call. Implementations own any data they choose to retain afterward.

§Example

use app_kit::{AppError, workflow::{LifecycleEvent, LifecycleHooks}};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
struct CountEvents(Arc<AtomicUsize>);
impl LifecycleHooks for CountEvents {
    fn observe(&self, event: &LifecycleEvent<'_>) -> Result<(), AppError> {
        if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
            self.0.fetch_add(1, Ordering::SeqCst);
        }
        Ok(())
    }
    fn observe_async<'a>(&'a self, event: &'a LifecycleEvent<'a>)
        -> impl std::future::Future<Output = Result<(), AppError>> + Send + 'a {
        async move {
            if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
                self.0.fetch_add(10, Ordering::SeqCst);
            }
            Ok(())
        }
    }
}
let run = "run_8a7c251e-b5b8-4d9e-8f0b-123456789abc".parse()?;
let event = LifecycleEvent::ExecuteStarted {
    run: &run, occurrence: "00000000000040008000000000000001",
};
let count = Arc::new(AtomicUsize::new(0));
let hooks = CountEvents(Arc::clone(&count));
hooks.observe(&event)?;
runtime.block_on(hooks.observe_async(&event))?;
assert_eq!(count.load(Ordering::SeqCst), 11);

Provided Methods§

Source

fn observe(&self, _event: &LifecycleEvent<'_>) -> Result<(), AppError>

Observes one event synchronously; the default has no effect.

§Errors

Return an error to report functional observation failure. App preserves an earlier execution failure as the structured cause of WorkflowFailure::Hook; a post-commit hook error does not roll back an accepted native commit.

§Example
use app_kit::{AppError, workflow::{LifecycleEvent, LifecycleHooks}};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
struct CountEvents(Arc<AtomicUsize>);
impl LifecycleHooks for CountEvents {
    fn observe(&self, event: &LifecycleEvent<'_>) -> Result<(), AppError> {
        if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
            self.0.fetch_add(1, Ordering::SeqCst);
        }
        Ok(())
    }
    fn observe_async<'a>(&'a self, event: &'a LifecycleEvent<'a>)
        -> impl std::future::Future<Output = Result<(), AppError>> + Send + 'a {
        async move {
            if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
                self.0.fetch_add(10, Ordering::SeqCst);
            }
            Ok(())
        }
    }
}
let run = "run_8a7c251e-b5b8-4d9e-8f0b-123456789abc".parse()?;
let event = LifecycleEvent::ExecuteStarted {
    run: &run, occurrence: "00000000000040008000000000000001",
};
let count = Arc::new(AtomicUsize::new(0));
CountEvents(Arc::clone(&count)).observe(&event)?;
assert_eq!(count.load(Ordering::SeqCst), 1);
Source

fn observe_async<'a>( &'a self, _event: &'a LifecycleEvent<'a>, ) -> impl Future<Output = Result<(), AppError>> + Send + 'a

Observes one event asynchronously; the default has no effect.

§Errors

Return an error to report functional observation failure. App preserves an earlier execution failure as the structured cause of WorkflowFailure::Hook; a post-commit hook error does not roll back an accepted native commit.

§Example
use app_kit::{AppError, workflow::{LifecycleEvent, LifecycleHooks}};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
struct CountEvents(Arc<AtomicUsize>);
impl LifecycleHooks for CountEvents {
    fn observe(&self, event: &LifecycleEvent<'_>) -> Result<(), AppError> {
        if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
            self.0.fetch_add(1, Ordering::SeqCst);
        }
        Ok(())
    }
    fn observe_async<'a>(&'a self, event: &'a LifecycleEvent<'a>)
        -> impl std::future::Future<Output = Result<(), AppError>> + Send + 'a {
        async move {
            if matches!(event, LifecycleEvent::ExecuteStarted { .. }) {
                self.0.fetch_add(10, Ordering::SeqCst);
            }
            Ok(())
        }
    }
}
let run = "run_8a7c251e-b5b8-4d9e-8f0b-123456789abc".parse()?;
let event = LifecycleEvent::ExecuteStarted {
    run: &run, occurrence: "00000000000040008000000000000001",
};
let count = Arc::new(AtomicUsize::new(0));
let hooks = CountEvents(Arc::clone(&count));
runtime.block_on(hooks.observe_async(&event))?;
assert_eq!(count.load(Ordering::SeqCst), 10);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§