-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathmod.rs
More file actions
162 lines (139 loc) · 4.87 KB
/
mod.rs
File metadata and controls
162 lines (139 loc) · 4.87 KB
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
use std::fmt::Display;
pub mod config;
mod execution_context;
mod helpers;
mod interfaces;
mod memory;
mod shared;
#[cfg(test)]
mod tests;
mod valgrind;
mod wall_time;
use crate::instruments::mongo_tracer::{MongoTracer, install_mongodb_tracer};
use crate::prelude::*;
use crate::runner_mode::RunnerMode;
use crate::system::SystemInfo;
use crate::upload::UploadResult;
use async_trait::async_trait;
pub use config::Config;
pub use execution_context::ExecutionContext;
pub use helpers::profile_folder::create_profile_folder;
pub use interfaces::ExecutorName;
use memory::executor::MemoryExecutor;
use std::path::Path;
use valgrind::executor::ValgrindExecutor;
use wall_time::executor::WallTimeExecutor;
impl Display for RunnerMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
#[allow(deprecated)]
RunnerMode::Instrumentation => write!(f, "instrumentation"),
RunnerMode::Simulation => write!(f, "simulation"),
RunnerMode::Walltime => write!(f, "walltime"),
RunnerMode::Memory => write!(f, "memory"),
}
}
}
pub const EXECUTOR_TARGET: &str = "executor";
pub fn get_executor_from_mode(mode: &RunnerMode) -> Box<dyn Executor> {
match mode {
#[allow(deprecated)]
RunnerMode::Instrumentation | RunnerMode::Simulation => Box::new(ValgrindExecutor),
RunnerMode::Walltime => Box::new(WallTimeExecutor::new()),
RunnerMode::Memory => Box::new(MemoryExecutor),
}
}
pub fn get_all_executors() -> Vec<Box<dyn Executor>> {
vec![
Box::new(ValgrindExecutor),
Box::new(WallTimeExecutor::new()),
Box::new(MemoryExecutor),
]
}
#[async_trait(?Send)]
pub trait Executor {
fn name(&self) -> ExecutorName;
async fn setup(
&self,
_system_info: &SystemInfo,
_setup_cache_dir: Option<&Path>,
) -> Result<()> {
Ok(())
}
/// Runs the executor
async fn run(
&self,
execution_context: &ExecutionContext,
// TODO: use Instruments instead of directly passing the mongodb tracer
mongo_tracer: &Option<MongoTracer>,
) -> Result<()>;
async fn teardown(&self, execution_context: &ExecutionContext) -> Result<()>;
}
/// Execute benchmarks with the given configuration
/// This is the core execution logic shared between `run` and `exec` commands
pub async fn execute_benchmarks<F>(
executor: &dyn Executor,
execution_context: &mut ExecutionContext,
setup_cache_dir: Option<&Path>,
poll_results: F,
) -> Result<()>
where
F: AsyncFn(&UploadResult) -> Result<()>,
{
if !execution_context.config.skip_setup {
executor
.setup(&execution_context.system_info, setup_cache_dir)
.await?;
// TODO: refactor and move directly in the Instruments struct as a `setup` method
if execution_context.config.instruments.is_mongodb_enabled() {
install_mongodb_tracer().await?;
}
debug!("Environment ready");
}
if !execution_context.config.skip_run {
start_opened_group!("Running the benchmarks");
// TODO: refactor and move directly in the Instruments struct as a `start` method
let mongo_tracer =
if let Some(mongodb_config) = &execution_context.config.instruments.mongodb {
let mut mongo_tracer =
MongoTracer::try_from(&execution_context.profile_folder, mongodb_config)?;
mongo_tracer.start().await?;
Some(mongo_tracer)
} else {
None
};
executor.run(execution_context, &mongo_tracer).await?;
// TODO: refactor and move directly in the Instruments struct as a `stop` method
if let Some(mut mongo_tracer) = mongo_tracer {
mongo_tracer.stop().await?;
}
end_group!();
debug!("Tearing down the executor");
executor.teardown(execution_context).await?;
execution_context
.logger
.persist_log_to_profile_folder(execution_context)?;
} else {
debug!("Skipping the run of the benchmarks");
};
// Handle upload and polling
if !execution_context.config.skip_upload {
if !execution_context.is_local() {
// If relevant, set the OIDC token for authentication
// Note: OIDC tokens can expire quickly, so we set it just before the upload
execution_context
.provider
.set_oidc_token(&mut execution_context.config)
.await?;
}
start_group!("Uploading results");
let upload_result = crate::upload::upload(execution_context, executor.name()).await?;
if execution_context.is_local() {
poll_results(&upload_result).await?;
}
end_group!();
} else {
debug!("Skipping upload of performance data");
}
Ok(())
}