mecha10-core 0.8.0

Mecha10 core runtime and foundational types
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
//! Example usage of Distributed Tracing with Context Propagation
//!
//! This example demonstrates how trace context automatically propagates through
//! pub/sub messages, enabling end-to-end request tracing across distributed nodes.

use mecha10::prelude::*;
use serde::{Deserialize, Serialize};
use std::time::Duration;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct ImageMessage {
    width: u32,
    height: u32,
    timestamp: u64,
}
impl Message for ImageMessage {}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct DetectionResult {
    object_count: u32,
    confidence: f32,
}
impl Message for DetectionResult {}

/// Example 1: Basic trace context propagation
pub fn basic_propagation_example() -> Result<()> {
    info!("Example 1: Basic trace context propagation");

    let trace_ctx = TraceContext::new();

    info!("\nCreated trace context:");
    info!("  Trace ID: {}", trace_ctx.trace_id);
    info!("  Span ID: {}", trace_ctx.span_id);
    info!("  Sampled: {}", trace_ctx.sampled);

    let child_ctx = trace_ctx.child();

    info!("\nChild context:");
    info!("  Trace ID: {} (same as parent)", child_ctx.trace_id);
    info!("  Span ID: {} (new)", child_ctx.span_id);
    info!("  Parent Span ID: {:?}", child_ctx.parent_span_id);

    Ok(())
}

/// Example 2: W3C Trace Context format
pub fn w3c_format_example() -> Result<()> {
    info!("Example 2: W3C Trace Context format");

    let ctx = TraceContext::new();

    let traceparent = ctx.to_w3c_traceparent();
    info!("\nW3C traceparent: {}", traceparent);
    info!("  Format: version-trace_id-span_id-flags");

    let parsed = TraceContext::from_w3c_traceparent(&traceparent).unwrap();
    info!("\nParsed context:");
    info!("  Trace ID: {}", parsed.trace_id);
    info!("  Span ID: {}", parsed.span_id);
    info!("  Sampled: {}", parsed.sampled);

    Ok(())
}

/// Example 3: Baggage for metadata propagation
pub fn baggage_example() -> Result<()> {
    info!("Example 3: Baggage for metadata propagation");

    let ctx = TraceContext::new()
        .with_baggage("user_id", "user123")
        .with_baggage("request_id", "req_abc")
        .with_baggage("environment", "production");

    info!("\nBaggage items:");
    for (key, value) in &ctx.baggage {
        info!("  {}: {}", key, value);
    }

    info!("\nBaggage propagates with trace context,");
    info!("allowing metadata to flow through the system.");

    Ok(())
}

/// Example 4: TracedMessage envelope
pub fn traced_message_example() -> Result<()> {
    info!("Example 4: TracedMessage envelope");

    let image = ImageMessage {
        width: 640,
        height: 480,
        timestamp: now_micros(),
    };

    let traced = TracedMessage::new(image.clone(), "camera_node");

    info!("\nTracedMessage structure:");
    info!("  Payload: {:?}", traced.payload);
    info!("  Trace ID: {}", traced.trace_context.trace_id);
    info!("  Source: {}", traced.source_node);
    info!("  Timestamp: {}", traced.timestamp_us);

    let span = traced.create_span("process_image");
    let _guard = span.enter();

    info!("\nSpan created from message");
    info!("  All logs within this scope include trace context");

    Ok(())
}

/// Example 5: Publishing with trace context
pub async fn publish_traced_example() -> Result<()> {
    info!("Example 5: Publishing with trace context");

    info!("\nNormal publish:");
    info!("  ctx.publish(\"/topic\", &message).await");
    info!("  → No trace context");

    info!("\nTraced publish:");
    info!("  ctx.publish_traced(\"/topic\", &message).await");
    info!("  → Automatic trace context injection");
    info!("  → Creates child span for this publish");

    info!("\nPublish with explicit context:");
    info!("  ctx.publish_with_context(\"/topic\", &message, trace_ctx).await");
    info!("  → Use existing trace context");
    info!("  → Continue existing trace");

    Ok(())
}

/// Example 6: Subscribing with trace context
pub async fn subscribe_traced_example() -> Result<()> {
    info!("Example 6: Subscribing with trace context");

    info!("\nNormal subscribe:");
    info!("  let mut rx = ctx.subscribe(\"/topic\").await?;");
    info!("  while let Some(msg) = rx.recv().await {{ }}");
    info!("  → Message only");

    info!("\nTraced subscribe:");
    info!("  let mut rx = ctx.subscribe_traced(\"/topic\").await?;");
    info!("  while let Some(traced_msg) = rx.recv().await {{");
    info!("      let trace_ctx = traced_msg.trace_context;");
    info!("      let span = traced_msg.create_span(\"process\");");
    info!("      span.in_scope(|| {{");
    info!("          // Process within traced span");
    info!("      }});");
    info!("  }}");
    info!("  → Message + trace context");
    info!("  → Automatic span continuation");

    Ok(())
}

/// Example 7: End-to-end tracing scenario
pub fn end_to_end_scenario() -> Result<()> {
    info!("Example 7: End-to-end tracing scenario");

    info!("\nImage processing pipeline:");
    info!("  Camera → Detection → Tracking → Planning");

    let root_ctx = TraceContext::new()
        .with_baggage("pipeline", "vision")
        .with_baggage("frame_id", "1234");

    info!("\nStep 1: Camera captures image");
    info!("  Trace ID: {}", root_ctx.trace_id);
    info!("  Span: camera_capture");

    let detection_ctx = root_ctx.child();
    info!("\nStep 2: Detection processes image");
    info!("  Trace ID: {} (same)", detection_ctx.trace_id);
    info!("  Span: object_detection");
    info!("  Parent: {}", root_ctx.span_id);

    let tracking_ctx = detection_ctx.child();
    info!("\nStep 3: Tracking updates state");
    info!("  Trace ID: {} (same)", tracking_ctx.trace_id);
    info!("  Span: object_tracking");
    info!("  Parent: {}", detection_ctx.span_id);

    let planning_ctx = tracking_ctx.child();
    info!("\nStep 4: Planning makes decision");
    info!("  Trace ID: {} (same)", planning_ctx.trace_id);
    info!("  Span: path_planning");
    info!("  Parent: {}", tracking_ctx.span_id);

    info!("\nAll spans share the same trace ID,");
    info!("enabling visualization of the complete flow!");

    Ok(())
}

/// Example 8: Sampling configuration
pub fn sampling_example() -> Result<()> {
    info!("Example 8: Sampling configuration");

    info!("\nFull sampling (100%):");
    let config = TracingConfig::default()
        .with_service_name("robot-vision")
        .with_sampling_rate(1.0);
    info!("  Every request is traced");
    info!("  Sampling rate: {}", config.sampling_rate);

    info!("\nPartial sampling (10%):");
    let config = TracingConfig::default()
        .with_service_name("robot-vision")
        .with_sampling_rate(0.1);
    info!("  1 in 10 requests traced");
    info!("  Reduces overhead in production");
    info!("  Sampling rate: {}", config.sampling_rate);

    info!("\nNo sampling (0%):");
    let config = TracingConfig::default()
        .with_service_name("robot-vision")
        .with_sampling_rate(0.0);
    info!("  Tracing disabled");
    info!("  Sampling rate: {}", config.sampling_rate);

    Ok(())
}

/// Example 9: Exporter configuration
pub fn exporter_configuration() -> Result<()> {
    info!("Example 9: Exporter configuration");

    info!("\nJaeger exporter:");
    let config = TracingConfig::default()
        .with_service_name("my-robot")
        .with_jaeger("http://localhost:14268/api/traces");
    info!("  Service: {}", config.service_name);
    info!("  Endpoint: {:?}", config.jaeger_endpoint);

    info!("\nZipkin exporter:");
    let config = TracingConfig::default()
        .with_service_name("my-robot")
        .with_zipkin("http://localhost:9411/api/v2/spans");
    info!("  Service: {}", config.service_name);
    info!("  Endpoint: {:?}", config.zipkin_endpoint);

    info!("\nBoth exporters:");
    let config = TracingConfig::default()
        .with_service_name("my-robot")
        .with_jaeger("http://jaeger:14268/api/traces")
        .with_zipkin("http://zipkin:9411/api/v2/spans");
    info!("  Traces sent to both Jaeger and Zipkin");

    Ok(())
}

/// Example 10: Real-world usage pattern
pub fn real_world_pattern() -> Result<()> {
    info!("Example 10: Real-world usage pattern");

    info!("\nTypical node implementation:");
    info!("```rust");
    info!("async fn run(&mut self, ctx: &Context) -> Result<()> {{");
    info!("    // Subscribe with tracing");
    info!("    let mut images = ctx.subscribe_traced(\"/camera/rgb\").await?;");
    info!("");
    info!("    while let Some(traced_msg) = images.recv().await {{");
    info!("        // Extract trace context");
    info!("        let trace_ctx = traced_msg.trace_context;");
    info!("        let image = traced_msg.payload;");
    info!("");
    info!("        // Create span for processing");
    info!("        let span = traced_msg.create_span(\"detect_objects\");");
    info!("        let _guard = span.enter();");
    info!("");
    info!("        // Process (all logs include trace context)");
    info!("        let detections = detect_objects(&image);");
    info!("");
    info!("        // Publish with continued trace");
    info!("        ctx.publish_with_context(");
    info!("            \"/perception/detections\",");
    info!("            &detections,");
    info!("            trace_ctx,");
    info!("        ).await?;");
    info!("    }}");
    info!("}}");
    info!("```");

    Ok(())
}

/// Example 11: Trace visualization
pub fn trace_visualization() -> Result<()> {
    info!("Example 11: Trace visualization");

    info!("\nIn Jaeger UI, you can see:");
    info!("  • Request timeline");
    info!("  • Service dependencies");
    info!("  • Span durations");
    info!("  • Error locations");
    info!("  • Baggage metadata");

    info!("\nExample trace:");
    info!("┌─────────────────────────────────────────────────────┐");
    info!("│ Trace: a1b2c3d4e5f6                      Duration: 145ms │");
    info!("├─────────────────────────────────────────────────────┤");
    info!("│ camera_node → camera_capture              5ms       │");
    info!("│   vision_node → object_detection         80ms      │");
    info!("│     tracking_node → update_tracks        35ms      │");
    info!("│       planner_node → plan_path           25ms      │");
    info!("└─────────────────────────────────────────────────────┘");

    Ok(())
}

/// Example 12: Performance impact
pub fn performance_impact() -> Result<()> {
    info!("Example 12: Performance impact");

    info!("\nTracing overhead:");
    info!("  Trace context creation:     ~1-2 µs");
    info!("  Context serialization:      ~5-10 µs");
    info!("  Span creation:              ~2-3 µs");
    info!("  Export (async, batched):    ~100-500 µs");

    info!("\nMitigation strategies:");
    info!("  • Use sampling (e.g., 10%)");
    info!("  • Batch export spans");
    info!("  • Async export to avoid blocking");
    info!("  • Disable in tight loops");

    info!("\nRecommendations:");
    info!("  Development:  100% sampling");
    info!("  Staging:       50% sampling");
    info!("  Production:    5-10% sampling");

    Ok(())
}

fn main() -> Result<()> {
    tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();

    println!("Distributed Tracing with Context Propagation");
    println!("============================================\n");
    println!("End-to-end request tracing across distributed nodes.");
    println!();

    let runtime = tokio::runtime::Runtime::new().unwrap();

    runtime.block_on(async {
        basic_propagation_example()?;
        println!();

        w3c_format_example()?;
        println!();

        baggage_example()?;
        println!();

        traced_message_example()?;
        println!();

        publish_traced_example().await?;
        println!();

        subscribe_traced_example().await?;
        println!();

        end_to_end_scenario()?;
        println!();

        sampling_example()?;
        println!();

        exporter_configuration()?;
        println!();

        real_world_pattern()?;
        println!();

        trace_visualization()?;
        println!();

        performance_impact()?;
        println!();

        Ok::<(), Mecha10Error>(())
    })?;

    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("All examples completed!");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    println!("Key Features:");
    println!("  ✓ Automatic trace context propagation");
    println!("  ✓ W3C Trace Context standard");
    println!("  ✓ Parent-child span relationships");
    println!("  ✓ Baggage for metadata");
    println!("  ✓ Configurable sampling");
    println!("  ✓ Multiple exporters (Jaeger, Zipkin)");
    println!();
    println!("Benefits:");
    println!("  • Debug distributed systems");
    println!("  • Identify performance bottlenecks");
    println!("  • Understand service dependencies");
    println!("  • Track requests end-to-end");
    println!("  • Correlate logs across nodes");

    Ok(())
}