don't cache external job failures if they could be caused by the user killing processes
This commit is contained in:
parent
7dc4417874
commit
edcc5927a5
1 changed files with 46 additions and 10 deletions
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
};
|
||||
use base64::{Engine, prelude::BASE64_URL_SAFE_NO_PAD};
|
||||
use clap::builder::OsStringValueParser;
|
||||
use eyre::{Context, bail, ensure, eyre};
|
||||
use eyre::{Context, ensure, eyre};
|
||||
use serde::{
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
de::{DeserializeOwned, Error},
|
||||
|
|
@ -26,6 +26,7 @@ use std::{
|
|||
io::Write,
|
||||
marker::PhantomData,
|
||||
path::{Path, PathBuf},
|
||||
process::ExitStatus,
|
||||
sync::OnceLock,
|
||||
};
|
||||
|
||||
|
|
@ -365,13 +366,17 @@ impl ExternalJobCaching {
|
|||
.stdin(std::process::Stdio::null());
|
||||
Ok(cmd)
|
||||
}
|
||||
pub fn run<F: FnOnce(std::process::Command) -> eyre::Result<()>>(
|
||||
pub fn run<F>(
|
||||
self,
|
||||
command_line: Interned<[Interned<OsStr>]>,
|
||||
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
||||
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
||||
run_fn: F,
|
||||
) -> eyre::Result<()> {
|
||||
exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(std::process::Command) -> eyre::Result<Result<(), ExitStatus>>,
|
||||
{
|
||||
let mut hasher = JobCacheHasher::default();
|
||||
hasher.hash_iter(command_line.iter(), |hasher, arg| {
|
||||
hasher.hash_sized_os_str(arg)
|
||||
|
|
@ -419,7 +424,26 @@ impl ExternalJobCaching {
|
|||
})
|
||||
.expect("spawn shouldn't fail");
|
||||
run_fn(cmd)
|
||||
});
|
||||
})?;
|
||||
if let Err(exit_status) = result {
|
||||
// check if the user may have terminated it or something, don't cache the failure
|
||||
let user_maybe_terminated;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
user_maybe_terminated = std::os::unix::process::ExitStatusExt::signal(&exit_status)
|
||||
.is_some()
|
||||
|| exit_status.code().is_none_or(|code| code > 1);
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
user_maybe_terminated = !exit_status.success();
|
||||
}
|
||||
if user_maybe_terminated {
|
||||
let _ = std::fs::remove_file(self.cache_json_path);
|
||||
return Err(exit_status_to_error(exit_status));
|
||||
}
|
||||
}
|
||||
let result = result.map_err(exit_status_to_error);
|
||||
ExternalJobCacheV2 {
|
||||
version: ExternalJobCacheVersion::CURRENT,
|
||||
inputs_hash,
|
||||
|
|
@ -444,16 +468,26 @@ impl ExternalJobCaching {
|
|||
.write_to_file(self.cache_json_path)?;
|
||||
result
|
||||
}
|
||||
pub fn run_maybe_cached<F: FnOnce(std::process::Command) -> eyre::Result<()>>(
|
||||
pub fn run_maybe_cached<F>(
|
||||
this: Option<Self>,
|
||||
command_line: Interned<[Interned<OsStr>]>,
|
||||
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
||||
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
||||
run_fn: F,
|
||||
) -> eyre::Result<()> {
|
||||
exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(std::process::Command) -> eyre::Result<Result<(), ExitStatus>>,
|
||||
{
|
||||
match this {
|
||||
Some(this) => this.run(command_line, input_file_paths, output_file_paths, run_fn),
|
||||
None => run_fn(Self::make_command(command_line)?),
|
||||
Some(this) => this.run(
|
||||
command_line,
|
||||
input_file_paths,
|
||||
output_file_paths,
|
||||
run_fn,
|
||||
exit_status_to_error,
|
||||
),
|
||||
None => run_fn(Self::make_command(command_line)?)?.map_err(exit_status_to_error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1119,10 +1153,12 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
|||
}
|
||||
let status = acquired_job.run_command(cmd, |cmd| cmd.status())?;
|
||||
if !status.success() {
|
||||
bail!("running {command_line:?} failed: {status}")
|
||||
Ok(Err(status))
|
||||
} else {
|
||||
Ok(Ok(()))
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
|status| eyre!("running {command_line:?} failed: {status}"),
|
||||
)?;
|
||||
Ok(job
|
||||
.output_paths()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue