Files
wifi-densepose/docs/examples/monitoring_example.md
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

6.0 KiB

Real-Time Monitoring Example

This example demonstrates the event-driven monitoring system for the dynamic minimum cut algorithm.

Basic Usage

use ruvector_mincut::monitoring::{MinCutMonitor, MonitorConfig, EventType};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};

// Create a monitor with default configuration
let monitor = MinCutMonitor::new(MonitorConfig::default());

// Register a callback for all events
let counter = Arc::new(AtomicU64::new(0));
let counter_clone = counter.clone();

monitor.on_event("event_counter", move |event| {
    counter_clone.fetch_add(1, Ordering::SeqCst);
    println!("Event: {:?}, New cut: {}", event.event_type, event.new_value);
}).unwrap();

// Simulate cut changes
monitor.notify(0.0, 10.0, None);
monitor.notify(10.0, 5.0, None);

// Check metrics
let metrics = monitor.metrics();
println!("Total events: {}", metrics.total_events);
println!("Average cut: {}", metrics.avg_cut);

Event Type Filtering

use std::sync::atomic::AtomicU64;

let monitor = MinCutMonitor::new(MonitorConfig::default());
let decrease_counter = Arc::new(AtomicU64::new(0));
let counter_clone = decrease_counter.clone();

// Only track when cut decreases
monitor.on_event_type(EventType::CutDecreased, "decrease_tracker", move |event| {
    counter_clone.fetch_add(1, Ordering::SeqCst);
    println!("Cut decreased from {} to {}", event.old_value, event.new_value);
}).unwrap();

monitor.notify(10.0, 5.0, None);  // Triggers callback
monitor.notify(5.0, 15.0, None);  // Does not trigger

Threshold Monitoring

use ruvector_mincut::monitoring::{Threshold, MonitorBuilder};

let alert_counter = Arc::new(AtomicU64::new(0));
let counter_clone = alert_counter.clone();

// Build monitor with thresholds
let monitor = MonitorBuilder::new()
    .threshold_below(10.0, "critical")    // Alert when cut goes below 10
    .threshold_above(100.0, "warning")    // Alert when cut goes above 100
    .on_event_type(EventType::ThresholdCrossedBelow, "alert", move |event| {
        counter_clone.fetch_add(1, Ordering::SeqCst);
        println!("CRITICAL: Cut crossed below threshold!");
    })
    .build();

// Cross the threshold
monitor.notify(50.0, 5.0, None);  // Triggers alert

// Check threshold status
let status = monitor.threshold_status();
for (name, active) in status {
    println!("Threshold '{}': {}", name, if active { "ACTIVE" } else { "inactive" });
}

Connectivity Monitoring

let disconnected_counter = Arc::new(AtomicU64::new(0));
let connected_counter = Arc::new(AtomicU64::new(0));

let disc_clone = disconnected_counter.clone();
let conn_clone = connected_counter.clone();

let monitor = MinCutMonitor::new(MonitorConfig::default());

monitor.on_event_type(EventType::Disconnected, "disc", move |_| {
    disc_clone.fetch_add(1, Ordering::SeqCst);
    println!("WARNING: Graph became disconnected!");
}).unwrap();

monitor.on_event_type(EventType::Connected, "conn", move |_| {
    conn_clone.fetch_add(1, Ordering::SeqCst);
    println!("Graph reconnected");
}).unwrap();

// Simulate disconnection
monitor.notify(10.0, 0.0, None);  // Graph disconnected

// Simulate reconnection
monitor.notify(0.0, 5.0, None);   // Graph connected

Custom Configuration

use std::time::Duration;

let config = MonitorConfig {
    max_callbacks: 50,                        // Allow up to 50 callbacks
    sample_interval: Duration::from_millis(100),  // Sample history every 100ms
    max_history_size: 500,                    // Keep last 500 samples
    collect_metrics: true,                    // Enable metrics collection
};

let monitor = MinCutMonitor::new(config);

Metrics Collection

let monitor = MinCutMonitor::new(MonitorConfig::default());

// Simulate various events
for i in 0..100 {
    let value = (i as f64 * 10.0) % 100.0;
    monitor.notify(value, value + 5.0, Some((i, i + 1)));
}

// Get metrics
let metrics = monitor.metrics();
println!("Total events: {}", metrics.total_events);
println!("Average cut: {:.2}", metrics.avg_cut);
println!("Min observed: {:.2}", metrics.min_observed);
println!("Max observed: {:.2}", metrics.max_observed);
println!("Events by type:");
for (event_type, count) in &metrics.events_by_type {
    println!("  {}: {}", event_type, count);
}
println!("History samples: {}", metrics.cut_history.len());

Thread-Safe Concurrent Monitoring

use std::thread;

let monitor = Arc::new(MinCutMonitor::new(MonitorConfig::default()));
let counter = Arc::new(AtomicU64::new(0));

// Register callbacks from multiple threads
for i in 0..10 {
    let monitor_clone = monitor.clone();
    let counter_clone = counter.clone();

    monitor_clone.on_event(&format!("callback_{}", i), move |_| {
        counter_clone.fetch_add(1, Ordering::SeqCst);
    }).unwrap();
}

// Trigger events from multiple threads
let handles: Vec<_> = (0..5).map(|i| {
    let monitor_clone = monitor.clone();
    thread::spawn(move || {
        monitor_clone.notify(i as f64, (i + 1) as f64, None);
    })
}).collect();

for handle in handles {
    handle.join().unwrap();
}

println!("Total callback invocations: {}", counter.load(Ordering::SeqCst));

Key Features

Event-Driven Architecture

  • Non-blocking callbacks: Callbacks are executed synchronously but errors are caught
  • Event filtering: Register callbacks for specific event types
  • Panic safety: Callbacks that panic are caught and logged

Threshold Monitoring

  • Hysteresis: Prevents alert storms by only triggering on state transitions
  • Bi-directional: Support for "below" and "above" threshold alerts
  • Dynamic management: Add/remove thresholds at runtime

Metrics Collection

  • Running statistics: Average, min, max cut values
  • Event counting: Track events by type
  • Sampled history: Time-series data with configurable sampling
  • Resource bounded: Automatic history size management

Thread Safety

  • Lock-free reads: RwLock allows concurrent reads
  • Safe updates: Write locks protect critical sections
  • Arc-friendly: Safe to share across threads