Compare commits

...

1 Commits

Author SHA1 Message Date
Thorsten Ball
d4c4acf1fa npm: Use timeout in Rust to avoid npm blocking 2024-05-16 17:08:35 +02:00

View File

@@ -7,10 +7,12 @@ use futures::AsyncReadExt;
use http::HttpClient; use http::HttpClient;
use semver::Version; use semver::Version;
use serde::Deserialize; use serde::Deserialize;
use smol::future::FutureExt;
use smol::io::BufReader; use smol::io::BufReader;
use smol::{fs, lock::Mutex, process::Command}; use smol::{fs, lock::Mutex, process::Command};
use std::io; use std::io;
use std::process::{Output, Stdio}; use std::process::{Output, Stdio};
use std::time::Duration;
use std::{ use std::{
env::consts, env::consts,
path::{Path, PathBuf}, path::{Path, PathBuf},
@@ -297,11 +299,7 @@ impl NodeRuntime for RealNodeRuntime {
} }
async fn npm_package_latest_version(&self, name: &str) -> Result<String> { async fn npm_package_latest_version(&self, name: &str) -> Result<String> {
let output = self let args = [
.run_npm_subcommand(
None,
"info",
&[
name, name,
"--json", "--json",
"--fetch-retry-mintimeout", "--fetch-retry-mintimeout",
@@ -310,8 +308,15 @@ impl NodeRuntime for RealNodeRuntime {
"5000", "5000",
"--fetch-timeout", "--fetch-timeout",
"5000", "5000",
], ];
) let npm_info_task = self.run_npm_subcommand(None, "info", &args);
let output = npm_info_task
.race(async {
// We have a manual timer here, because `npm info` does block infinitely when offline.
smol::Timer::after(Duration::from_secs(6)).await;
Err(anyhow!("fetching latest npm version timed out"))
})
.await?; .await?;
let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?;