mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 02:48:24 +00:00
fix: attempt to only allow one deno process to update the node_modules folder at a time (#18058)
This is implemented in such a way that it should still allow processes to go through when a file lock wasn't properly cleaned up and the OS hasn't released it yet (but with a 200ms-ish delay). Closes #18039
This commit is contained in:
parent
72fe9bb470
commit
88b5fd9088
8 changed files with 301 additions and 7 deletions
|
@ -23,6 +23,21 @@ mod renderer;
|
|||
// Inspired by Indicatif, but this custom implementation allows
|
||||
// for more control over what's going on under the hood.
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ProgressMessagePrompt {
|
||||
Download,
|
||||
Blocking,
|
||||
}
|
||||
|
||||
impl ProgressMessagePrompt {
|
||||
pub fn as_text(&self) -> String {
|
||||
match self {
|
||||
ProgressMessagePrompt::Download => colors::green("Download").to_string(),
|
||||
ProgressMessagePrompt::Blocking => colors::cyan("Blocking").to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UpdateGuard {
|
||||
maybe_entry: Option<ProgressBarEntry>,
|
||||
|
@ -59,6 +74,7 @@ pub enum ProgressBarStyle {
|
|||
#[derive(Clone, Debug)]
|
||||
struct ProgressBarEntry {
|
||||
id: usize,
|
||||
prompt: ProgressMessagePrompt,
|
||||
pub message: String,
|
||||
pos: Arc<AtomicU64>,
|
||||
total_size: Arc<AtomicU64>,
|
||||
|
@ -128,11 +144,16 @@ impl ProgressBarInner {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_entry(&self, message: String) -> ProgressBarEntry {
|
||||
pub fn add_entry(
|
||||
&self,
|
||||
kind: ProgressMessagePrompt,
|
||||
message: String,
|
||||
) -> ProgressBarEntry {
|
||||
let mut internal_state = self.state.lock();
|
||||
let id = internal_state.total_entries;
|
||||
let entry = ProgressBarEntry {
|
||||
id,
|
||||
prompt: kind,
|
||||
message,
|
||||
pos: Default::default(),
|
||||
total_size: Default::default(),
|
||||
|
@ -208,6 +229,7 @@ impl DrawThreadRenderer for ProgressBarInner {
|
|||
pending_entries: state.entries.len(),
|
||||
total_entries: state.total_entries,
|
||||
display_entry: ProgressDataDisplayEntry {
|
||||
prompt: preferred_entry.prompt,
|
||||
message: preferred_entry.message.clone(),
|
||||
position: preferred_entry.position(),
|
||||
total_size: preferred_entry.total_size(),
|
||||
|
@ -255,9 +277,17 @@ impl ProgressBar {
|
|||
}
|
||||
|
||||
pub fn update(&self, msg: &str) -> UpdateGuard {
|
||||
self.update_with_prompt(ProgressMessagePrompt::Download, msg)
|
||||
}
|
||||
|
||||
pub fn update_with_prompt(
|
||||
&self,
|
||||
kind: ProgressMessagePrompt,
|
||||
msg: &str,
|
||||
) -> UpdateGuard {
|
||||
match &self.inner {
|
||||
Some(inner) => {
|
||||
let entry = inner.add_entry(msg.to_string());
|
||||
let entry = inner.add_entry(kind, msg.to_string());
|
||||
UpdateGuard {
|
||||
maybe_entry: Some(entry),
|
||||
}
|
||||
|
@ -265,7 +295,7 @@ impl ProgressBar {
|
|||
None => {
|
||||
// if we're not running in TTY, fallback to using logger crate
|
||||
if !msg.is_empty() {
|
||||
log::log!(log::Level::Info, "{} {}", colors::green("Download"), msg);
|
||||
log::log!(log::Level::Info, "{} {}", kind.as_text(), msg);
|
||||
}
|
||||
UpdateGuard { maybe_entry: None }
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@ use deno_runtime::colors;
|
|||
|
||||
use crate::util::display::human_download_size;
|
||||
|
||||
use super::ProgressMessagePrompt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProgressDataDisplayEntry {
|
||||
pub prompt: ProgressMessagePrompt,
|
||||
pub message: String,
|
||||
pub position: u64,
|
||||
pub total_size: u64,
|
||||
|
@ -142,7 +145,7 @@ impl ProgressBarRenderer for TextOnlyProgressBarRenderer {
|
|||
|
||||
format!(
|
||||
"{} {}{}{}",
|
||||
colors::green("Download"),
|
||||
data.display_entry.prompt.as_text(),
|
||||
data.display_entry.message,
|
||||
colors::gray(bytes_text),
|
||||
colors::gray(total_text),
|
||||
|
@ -195,6 +198,7 @@ mod test {
|
|||
let renderer = BarProgressBarRenderer;
|
||||
let mut data = ProgressData {
|
||||
display_entry: ProgressDataDisplayEntry {
|
||||
prompt: ProgressMessagePrompt::Download,
|
||||
message: "data".to_string(),
|
||||
position: 0,
|
||||
total_size: 10 * BYTES_TO_KIB,
|
||||
|
@ -251,6 +255,7 @@ mod test {
|
|||
let renderer = TextOnlyProgressBarRenderer;
|
||||
let mut data = ProgressData {
|
||||
display_entry: ProgressDataDisplayEntry {
|
||||
prompt: ProgressMessagePrompt::Blocking,
|
||||
message: "data".to_string(),
|
||||
position: 0,
|
||||
total_size: 10 * BYTES_TO_KIB,
|
||||
|
@ -263,7 +268,7 @@ mod test {
|
|||
};
|
||||
let text = renderer.render(data.clone());
|
||||
let text = test_util::strip_ansi_codes(&text);
|
||||
assert_eq!(text, "Download data 0.00KiB/10.00KiB (2/3)");
|
||||
assert_eq!(text, "Blocking data 0.00KiB/10.00KiB (2/3)");
|
||||
|
||||
data.pending_entries = 0;
|
||||
data.total_entries = 1;
|
||||
|
@ -271,6 +276,6 @@ mod test {
|
|||
data.display_entry.total_size = 0;
|
||||
let text = renderer.render(data);
|
||||
let text = test_util::strip_ansi_codes(&text);
|
||||
assert_eq!(text, "Download data");
|
||||
assert_eq!(text, "Blocking data");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue