data,apt/release,distro_info,new: replace lazy_static with LazyLock
Unify the lazily-initialized statics on std::sync::LazyLock, which the newer code already uses: the embed_data! macro expands to a plain static now, which also removes the visibility-forwarding workaround the lazy_static! matcher forced on it (the @expand arm wrapping vis in parentheses), and the 'static ref' spelling is kept at the call sites. distro_info's HTTP client, the apt keyring cache and the new-template registry follow the same pattern.
This commit is contained in:
+5
-6
@@ -45,7 +45,6 @@
|
|||||||
//! keyserver responses are armored) are dearmored in-process, so no `gpg`
|
//! keyserver responses are armored) are dearmored in-process, so no `gpg`
|
||||||
//! binary is needed.
|
//! binary is needed.
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -53,6 +52,7 @@ use std::error::Error;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::LazyLock;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::sync::PoisonError;
|
use std::sync::PoisonError;
|
||||||
|
|
||||||
@@ -793,11 +793,10 @@ async fn fetch_optional(url: &str) -> Option<Vec<u8>> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
/// Downloaded keyrings, keyed by URL: keyrings are small but would
|
||||||
/// Downloaded keyrings, keyed by URL: keyrings are small but would
|
/// otherwise be re-downloaded once per series/pocket lookup
|
||||||
/// otherwise be re-downloaded once per series/pocket lookup
|
static KEYRING_CACHE: LazyLock<Mutex<HashMap<String, Vec<u8>>>> =
|
||||||
static ref KEYRING_CACHE: Mutex<HashMap<String, Vec<u8>>> = Mutex::new(HashMap::new());
|
LazyLock::new(|| Mutex::new(HashMap::new()));
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the keyring cache, ignoring poisoning (the map is only corrupted on
|
/// Read the keyring cache, ignoring poisoning (the map is only corrupted on
|
||||||
/// panics, in which case a fresh map is just as good)
|
/// panics, in which case a fresh map is just as good)
|
||||||
|
|||||||
+13
-24
@@ -13,7 +13,7 @@
|
|||||||
//! data/quirks.yml) through the [`embed_data!`] macro below, so data
|
//! data/quirks.yml) through the [`embed_data!`] macro below, so data
|
||||||
//! and its accessors stay together and a diff touching one domain cannot
|
//! and its accessors stay together and a diff touching one domain cannot
|
||||||
//! half-touch another. The macro embeds the file at compile time and
|
//! half-touch another. The macro embeds the file at compile time and
|
||||||
//! parses it once into a `lazy_static` on first use; since the data ships
|
//! parses it once into a [`LazyLock`] on first use; since the data ships
|
||||||
//! inside the binary, a parse failure is a build-time bug that cannot be
|
//! inside the binary, a parse failure is a build-time bug that cannot be
|
||||||
//! recovered from at runtime, and the macro panics on it.
|
//! recovered from at runtime, and the macro panics on it.
|
||||||
//!
|
//!
|
||||||
@@ -30,8 +30,9 @@
|
|||||||
/// the invoking source file (`"../data/distro_info.yml"` from
|
/// the invoking source file (`"../data/distro_info.yml"` from
|
||||||
/// `src/distro_info.rs`, `"../../data/host_keys.yml"` from
|
/// `src/distro_info.rs`, `"../../data/host_keys.yml"` from
|
||||||
/// `src/put/ssh.rs`, ...), and expands to the house `include_str!` →
|
/// `src/put/ssh.rs`, ...), and expands to the house `include_str!` →
|
||||||
/// `lazy_static` → parse pattern — only the embed+parse boilerplate is
|
/// parse-on-first-use pattern — only the embed+parse boilerplate is
|
||||||
/// generated.
|
/// generated. The `static ref` spelling is kept from the macro's
|
||||||
|
/// `lazy_static!` ancestry; it expands to a plain `LazyLock` static.
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// embed_data! {
|
/// embed_data! {
|
||||||
@@ -39,31 +40,19 @@
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
macro_rules! embed_data {
|
macro_rules! embed_data {
|
||||||
// Internal arm: the visibility arrives wrapped in parentheses (empty for
|
($vis:vis static ref $name:ident : $ty:ty = $path:literal) => {
|
||||||
// private statics) because `lazy_static!` only re-matches literal
|
// The YAML is include_str!'d at compile time and statically
|
||||||
// `pub`/`pub(...)` token sequences, not an opaque forwarded `vis`.
|
// valid; if it ever failed to parse it would be a build-time bug
|
||||||
(@expand ($($vis:tt)*) static ref $name:ident : $ty:ty = $path:literal) => {
|
// that cannot be recovered from at runtime, so panicking here is
|
||||||
lazy_static::lazy_static! {
|
// acceptable.
|
||||||
// The YAML is include_str!'d at compile time and statically
|
$vis static $name: ::std::sync::LazyLock<$ty> = ::std::sync::LazyLock::new(|| {
|
||||||
// valid; if it ever failed to parse it would be a build-time bug
|
serde_yaml::from_str(include_str!($path))
|
||||||
// that cannot be recovered from at runtime, so panicking here is
|
|
||||||
// acceptable.
|
|
||||||
$($vis)* static ref $name: $ty = serde_yaml::from_str(include_str!($path))
|
|
||||||
.expect(concat!(
|
.expect(concat!(
|
||||||
"built-in ",
|
"built-in ",
|
||||||
$path,
|
$path,
|
||||||
" data is statically valid and must parse"
|
" data is statically valid and must parse"
|
||||||
));
|
))
|
||||||
}
|
});
|
||||||
};
|
|
||||||
(static ref $name:ident : $ty:ty = $path:literal) => {
|
|
||||||
$crate::data::embed_data!(@expand () static ref $name : $ty = $path);
|
|
||||||
};
|
|
||||||
(pub static ref $name:ident : $ty:ty = $path:literal) => {
|
|
||||||
$crate::data::embed_data!(@expand (pub) static ref $name : $ty = $path);
|
|
||||||
};
|
|
||||||
(pub ($($vis:tt)+) static ref $name:ident : $ty:ty = $path:literal) => {
|
|
||||||
$crate::data::embed_data!(@expand (pub ($($vis)+)) static ref $name : $ty = $path);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -1,10 +1,10 @@
|
|||||||
use crate::data::embed_data;
|
use crate::data::embed_data;
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::LazyLock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -104,20 +104,20 @@ embed_data! {
|
|||||||
static ref DATA: Data = "../data/distro_info.yml"
|
static ref DATA: Data = "../data/distro_info.yml"
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
// Shared HTTP client used for all outgoing plain requests: timeouts keep
|
||||||
// Shared HTTP client used for all outgoing plain requests: timeouts keep
|
// a hanging remote (connect or transfer) from stalling pkh indefinitely.
|
||||||
// a hanging remote (connect or transfer) from stalling pkh indefinitely.
|
// The short pool idle timeout and TCP keepalive avoid reusing keep-alive
|
||||||
// The short pool idle timeout and TCP keepalive avoid reusing keep-alive
|
// connections that the remote closed in the meantime, which surfaces as
|
||||||
// connections that the remote closed in the meantime, which surfaces as
|
// spurious 'error sending request' failures on busy mirrors/CDNs.
|
||||||
// spurious 'error sending request' failures on busy mirrors/CDNs.
|
static HTTP_CLIENT: LazyLock<reqwest::Client> = LazyLock::new(|| {
|
||||||
static ref HTTP_CLIENT: reqwest::Client = reqwest::Client::builder()
|
reqwest::Client::builder()
|
||||||
.connect_timeout(Duration::from_secs(10))
|
.connect_timeout(Duration::from_secs(10))
|
||||||
.timeout(Duration::from_secs(30))
|
.timeout(Duration::from_secs(30))
|
||||||
.pool_idle_timeout(Duration::from_secs(10))
|
.pool_idle_timeout(Duration::from_secs(10))
|
||||||
.tcp_keepalive(Duration::from_secs(30))
|
.tcp_keepalive(Duration::from_secs(30))
|
||||||
.build()
|
.build()
|
||||||
.expect("building the shared HTTP client with static options cannot fail");
|
.expect("building the shared HTTP client with static options cannot fail")
|
||||||
}
|
});
|
||||||
|
|
||||||
/// Shared HTTP client with a connect timeout (10s) and a total request
|
/// Shared HTTP client with a connect timeout (10s) and a total request
|
||||||
/// timeout (30s), to be used for all outgoing plain HTTP(S) requests
|
/// timeout (30s), to be used for all outgoing plain HTTP(S) requests
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ pub mod rust;
|
|||||||
pub mod shell;
|
pub mod shell;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -478,15 +479,13 @@ static TEMPLATE_SOURCES: &[TemplateSources] = &[
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
/// The parsed registry: manifest data plus resolved hooks, in the
|
||||||
/// The parsed registry: manifest data plus resolved hooks, in the
|
/// order of [`TEMPLATE_SOURCES`] (wizard menu = detection priority).
|
||||||
/// order of [`TEMPLATE_SOURCES`] (wizard menu = detection priority).
|
static REGISTRY: LazyLock<Vec<Template>> = LazyLock::new(build_registry);
|
||||||
static ref REGISTRY: Vec<Template> = build_registry();
|
/// The registry ids ([`Template::id`]), cached for the `TemplateId`
|
||||||
/// The registry ids ([`Template::id`]), cached for the `TemplateId`
|
/// accessors.
|
||||||
/// accessors.
|
static REGISTRY_IDS: LazyLock<Vec<TemplateId>> =
|
||||||
static ref REGISTRY_IDS: Vec<TemplateId> =
|
LazyLock::new(|| REGISTRY.iter().map(Template::id).collect());
|
||||||
REGISTRY.iter().map(Template::id).collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse and cross-check every embedded manifest into the registry. The
|
/// Parse and cross-check every embedded manifest into the registry. The
|
||||||
/// files ship inside the binary, so anything malformed here is a build-time
|
/// files ship inside the binary, so anything malformed here is a build-time
|
||||||
|
|||||||
Reference in New Issue
Block a user