@@ -13,15 +13,18 @@ use crate::executor::helpers::run_command_with_log_pipe::run_command_with_log_pi
1313use crate :: executor:: helpers:: run_command_with_log_pipe:: run_command_with_log_pipe_and_callback;
1414use crate :: executor:: helpers:: run_with_env:: wrap_with_env;
1515use crate :: executor:: helpers:: run_with_sudo:: wrap_with_sudo;
16+ use crate :: executor:: shared:: fifo:: FifoBenchmarkData ;
1617use crate :: executor:: shared:: fifo:: RunnerFifo ;
1718use crate :: executor:: { ExecutionContext , ExecutorName , ExecutorSupport } ;
1819use crate :: instruments:: mongo_tracer:: MongoTracer ;
1920use crate :: prelude:: * ;
2021use crate :: runner_mode:: RunnerMode ;
2122use crate :: system:: { SupportedOs , SystemInfo } ;
2223use async_trait:: async_trait;
24+ use runner_shared:: artifacts:: ExecutionTimestamps ;
2325use runner_shared:: fifo:: Command as FifoCommand ;
2426use runner_shared:: fifo:: IntegrationMode ;
27+ use std:: cell:: OnceCell ;
2528use std:: fs:: canonicalize;
2629use std:: io:: Write ;
2730use std:: path:: Path ;
@@ -79,6 +82,10 @@ impl Drop for HookScriptsGuard {
7982
8083pub struct WallTimeExecutor {
8184 profiler : Option < Box < dyn Profiler > > ,
85+
86+ /// Stashed by [`Executor::run`] and consumed by [`Executor::teardown`] to
87+ /// hand the run's outputs to [`Profiler::finalize`].
88+ benchmark_state : OnceCell < ( FifoBenchmarkData , ExecutionTimestamps ) > ,
8289}
8390
8491impl WallTimeExecutor {
@@ -90,7 +97,10 @@ impl WallTimeExecutor {
9097 } else {
9198 None
9299 } ;
93- Self { profiler }
100+ Self {
101+ profiler,
102+ benchmark_state : OnceCell :: new ( ) ,
103+ }
94104 }
95105
96106 fn walltime_bench_cmd (
@@ -161,13 +171,21 @@ impl Executor for WallTimeExecutor {
161171 let ( _env_file, _script_file, cmd_builder) =
162172 WallTimeExecutor :: walltime_bench_cmd ( & execution_context. config , execution_context) ?;
163173
164- let status = match self . profiler . as_mut ( ) {
174+ // Split-borrow `self` so the closure inside `run_with_profiler` can
175+ // capture `benchmark_state` while we hold `&mut profiler`.
176+ let Self {
177+ profiler,
178+ benchmark_state,
179+ } = self ;
180+
181+ let status = match profiler. as_mut ( ) {
165182 Some ( profiler) if execution_context. config . enable_profiler => {
166183 run_with_profiler (
167184 profiler. as_mut ( ) ,
168185 cmd_builder,
169186 & execution_context. config ,
170187 & execution_context. profile_folder ,
188+ benchmark_state,
171189 )
172190 . await
173191 }
@@ -196,6 +214,14 @@ impl Executor for WallTimeExecutor {
196214 async fn teardown ( & self , execution_context : & ExecutionContext ) -> Result < ( ) > {
197215 debug ! ( "Copying files to the profile folder" ) ;
198216
217+ if let ( Some ( profiler) , Some ( ( fifo_data, timestamps) ) ) =
218+ ( & self . profiler , self . benchmark_state . get ( ) )
219+ {
220+ profiler
221+ . finalize ( fifo_data, timestamps, & execution_context. profile_folder )
222+ . await ?;
223+ }
224+
199225 validate_walltime_results (
200226 & execution_context. profile_folder ,
201227 execution_context. config . allow_empty ,
@@ -207,12 +233,13 @@ impl Executor for WallTimeExecutor {
207233
208234/// Drive a single benchmark run through a [`Profiler`]: wrap the command,
209235/// spawn it, dispatch FIFO commands from the integration into the profiler's
210- /// hooks, and finalize once the child exits .
236+ /// hooks, and stash the run's outputs for [`Profiler::finalize`] in teardown .
211237async fn run_with_profiler (
212238 profiler : & mut dyn Profiler ,
213239 cmd_builder : CommandBuilder ,
214240 config : & ExecutorConfig ,
215241 profile_folder : & Path ,
242+ benchmark_state : & OnceCell < ( FifoBenchmarkData , ExecutionTimestamps ) > ,
216243) -> Result < std:: process:: ExitStatus > {
217244 let wrapped = profiler
218245 . wrap_command ( cmd_builder, config, profile_folder)
@@ -247,9 +274,7 @@ async fn run_with_profiler(
247274 let ( timestamps, fifo_data, exit_status) =
248275 runner_fifo. handle_fifo_messages ( & mut child, on_cmd) . await ?;
249276
250- profiler
251- . finalize ( fifo_data, timestamps, profile_folder)
252- . await ?;
277+ let _ = benchmark_state. set ( ( fifo_data, timestamps) ) ;
253278
254279 Ok ( exit_status)
255280 } )
0 commit comments