modality_trace_recorder_plugin/
trace_recorder.rs1use crate::{AttrKeyIndex, Client, ContextHandle, TraceRecorderConfig};
2use async_trait::async_trait;
3use modality_api::{AttrVal, Nanoseconds};
4use modality_ingest_client::IngestError;
5use modality_ingest_protocol::InternedAttrKey;
6use std::collections::HashMap;
7use thiserror::Error;
8use trace_recorder_parser::{
9 snapshot, streaming,
10 time::{Frequency, Timestamp},
11 types::{ObjectHandle, STARTUP_TASK_NAME},
12};
13
14#[derive(Debug, Error)]
15pub enum Error {
16 #[error("Missing startup task ('{}') object properties", STARTUP_TASK_NAME)]
17 MissingStartupTaskProperties,
18
19 #[error("Failed to locate task properties for object handle {0}")]
20 TaskPropertiesLookup(ObjectHandle),
21
22 #[error("Failed to locate ISR properties for object handle {0}")]
23 IsrPropertiesLookup(ObjectHandle),
24
25 #[error(transparent)]
26 SnapshotTraceRecorder(#[from] snapshot::Error),
27
28 #[error(transparent)]
29 StreamingTraceRecorder(#[from] streaming::Error),
30
31 #[error("Encountered an error with the Deviant custom event configuration. {0}.")]
32 DeviantEvent(String),
33
34 #[error("Encountered an ingest client error. {0}")]
35 Ingest(#[from] IngestError),
36
37 #[error(
38 "Encountered and IO error while reading the input stream ({})",
39 .0.kind()
40 )]
41 Io(#[from] std::io::Error),
42}
43
44pub trait NanosecondsExt {
45 const ONE_SECOND: u64 = 1_000_000_000;
46
47 fn resolution_ns(&self) -> Option<Nanoseconds>;
48
49 fn lossy_timestamp_ns<T: Into<Timestamp>>(&self, ticks: T) -> Nanoseconds {
52 let t = ticks.into();
53 self.resolution_ns()
54 .map(|res| Nanoseconds::from(t.get_raw() * res.get_raw()))
55 .unwrap_or_else(|| t.get_raw().into())
56 }
57}
58
59impl NanosecondsExt for Frequency {
60 fn resolution_ns(&self) -> Option<Nanoseconds> {
61 if self.is_unitless() {
62 None
63 } else {
64 Nanoseconds::from(Self::ONE_SECOND / u64::from(self.get_raw())).into()
65 }
66 }
67}
68
69pub struct TimelineDetails<TAK> {
70 pub name_key: TAK,
71 pub name: String,
72 pub description_key: TAK,
73 pub description: String,
74 pub object_handle_key: TAK,
75 pub object_handle: ObjectHandle,
76}
77
78#[async_trait]
79pub trait TraceRecorderExt<TAK: AttrKeyIndex, EAK: AttrKeyIndex> {
80 fn startup_task_handle(&self) -> Result<ObjectHandle, Error>;
81
82 fn object_handle(&self, obj_name: &str) -> Option<ObjectHandle>;
83
84 fn timeline_details(
85 &self,
86 handle: ContextHandle,
87 startup_task_name: Option<&str>,
88 ) -> Result<TimelineDetails<TAK>, Error>;
89
90 async fn setup_common_timeline_attrs(
91 &self,
92 cfg: &TraceRecorderConfig,
93 client: &mut Client<TAK, EAK>,
94 ) -> Result<HashMap<InternedAttrKey, AttrVal>, Error>;
95}