hydrate_pipeline/
log_events.rs

1use crate::build::JobRequestor;
2use crate::JobId;
3use hydrate_base::hashing::{HashMap, HashSet};
4use hydrate_base::AssetId;
5use std::path::PathBuf;
6use std::sync::Arc;
7use uuid::Uuid;
8
9#[derive(Debug, Copy, Clone)]
10pub enum LogEventLevel {
11    Warning,
12    Error,
13    FatalError,
14}
15
16pub struct ImportLogEvent {
17    pub path: PathBuf,
18    pub asset_id: Option<AssetId>,
19    pub level: LogEventLevel,
20    pub message: String,
21}
22
23pub enum LogDataRef<'a> {
24    Import(&'a ImportLogData),
25    Build(&'a BuildLogData),
26    None,
27}
28
29pub enum LogData {
30    Import(Arc<ImportLogData>),
31    Build(Arc<BuildLogData>),
32}
33
34impl LogData {
35    pub fn id(&self) -> Uuid {
36        match self {
37            LogData::Import(x) => x.id,
38            LogData::Build(x) => x.id,
39        }
40    }
41
42    pub fn is_import(&self) -> bool {
43        match self {
44            LogData::Import(_) => true,
45            _ => false,
46        }
47    }
48
49    pub fn is_build(&self) -> bool {
50        match self {
51            LogData::Build(_) => true,
52            _ => false,
53        }
54    }
55
56    pub fn duration(&self) -> Option<std::time::Duration> {
57        match self {
58            LogData::Import(x) => x
59                .end_instant
60                .map(|end_instant| end_instant - x.start_instant),
61            LogData::Build(x) => x
62                .end_instant
63                .map(|end_instant| end_instant - x.start_instant),
64        }
65    }
66
67    pub fn start_time(&self) -> std::time::SystemTime {
68        match self {
69            LogData::Import(x) => x.start_time,
70            LogData::Build(x) => x.start_time,
71        }
72    }
73}
74
75pub struct ImportLogData {
76    pub(crate) id: Uuid,
77    pub(crate) start_instant: std::time::Instant,
78    pub(crate) end_instant: Option<std::time::Instant>,
79    pub(crate) start_time: std::time::SystemTime,
80    pub log_events: Vec<ImportLogEvent>,
81}
82
83impl ImportLogData {
84    pub fn log_events(&self) -> &[ImportLogEvent] {
85        &self.log_events
86    }
87}
88
89impl Default for ImportLogData {
90    fn default() -> Self {
91        ImportLogData {
92            id: Uuid::new_v4(),
93            start_instant: std::time::Instant::now(),
94            end_instant: None,
95            start_time: std::time::SystemTime::now(),
96            log_events: vec![],
97        }
98    }
99}
100
101#[derive(Debug)]
102pub struct BuildLogEvent {
103    pub asset_id: Option<AssetId>,
104    pub job_id: Option<JobId>,
105    pub level: LogEventLevel,
106    pub message: String,
107}
108
109pub struct BuildLogData {
110    pub(crate) id: Uuid,
111    pub(crate) start_instant: std::time::Instant,
112    pub(crate) end_instant: Option<std::time::Instant>,
113    pub(crate) start_time: std::time::SystemTime,
114    pub(crate) log_events: Vec<BuildLogEvent>,
115    pub(crate) requestors: HashMap<JobId, Vec<JobRequestor>>,
116}
117
118impl Default for BuildLogData {
119    fn default() -> Self {
120        BuildLogData {
121            id: Uuid::new_v4(),
122            start_instant: std::time::Instant::now(),
123            end_instant: None,
124            start_time: std::time::SystemTime::now(),
125            log_events: vec![],
126            requestors: Default::default(),
127        }
128    }
129}
130
131impl BuildLogData {
132    pub fn log_events(&self) -> &[BuildLogEvent] {
133        &self.log_events
134    }
135
136    pub fn assets_relying_on_job(
137        &self,
138        job_id: JobId,
139    ) -> Vec<AssetId> {
140        let mut assets = vec![];
141        let checked_requestors = HashSet::<JobId>::default();
142        let mut requestor_check_queue = vec![job_id];
143
144        while let Some(requestor) = requestor_check_queue.pop() {
145            for requestor in self.requestors.get(&requestor).unwrap() {
146                match requestor {
147                    JobRequestor::Builder(asset_id) => assets.push(*asset_id),
148                    JobRequestor::Job(job_id) => {
149                        if !checked_requestors.contains(job_id) {
150                            requestor_check_queue.push(*job_id)
151                        }
152                    }
153                }
154            }
155        }
156
157        assets
158    }
159}