Skip to content

Commit f15a9a3

Browse files
refactor: Replace lazy_static with std::sync::LazyLock (#827)
* refactor: Replace lazy_static with std::sync::LazyLock std::cell::LazyCell and std::sync::LazyLock were stabilized in Rust 1.80.0. We can now use the standard library types instead of the lazy_static crate. * fix: Fix new Clippy errors introduced in Rust 1.80.0 * chore: Bump Rust toolchain version in workflows * chore: Bump cargo-udeps to 0.1.50 in build workflow * chore: Update PR link in changelog * chore: Mark change as breaking in changelog * Apply suggestion Co-authored-by: Nick <[email protected]> * fix: Use correct link format in changelogs --------- Co-authored-by: Nick <[email protected]>
1 parent d33dce7 commit f15a9a3

File tree

22 files changed

+107
-86
lines changed

22 files changed

+107
-86
lines changed

.github/workflows/build.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ env:
1717
CARGO_TERM_COLOR: always
1818
CARGO_INCREMENTAL: '0'
1919
CARGO_PROFILE_DEV_DEBUG: '0'
20-
RUST_TOOLCHAIN_VERSION: "1.79.0"
20+
RUST_TOOLCHAIN_VERSION: "1.80.0"
2121
RUSTFLAGS: "-D warnings"
2222
RUSTDOCFLAGS: "-D warnings"
2323
RUST_LOG: "info"
@@ -37,7 +37,7 @@ jobs:
3737
- uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3
3838
with:
3939
key: udeps
40-
- run: cargo install --locked [email protected].47
40+
- run: cargo install --locked [email protected].50
4141
- run: cargo udeps --all-targets
4242

4343
run_cargodeny:

.github/workflows/pr_pre-commit.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66

77
env:
88
CARGO_TERM_COLOR: always
9-
RUST_TOOLCHAIN_VERSION: "1.79.0"
9+
RUST_TOOLCHAIN_VERSION: "1.80.0"
1010

1111
jobs:
1212
pre-commit:

Cargo.lock

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ json-patch = "2.0.0"
3232
k8s-openapi = { version = "0.22.0", default-features = false, features = ["schemars", "v1_30"] }
3333
# We use rustls instead of openssl for easier portablitly, e.g. so that we can build stackablectl without the need to vendor (build from source) openssl
3434
kube = { version = "0.92.1", default-features = false, features = ["client", "jsonpatch", "runtime", "derive", "rustls-tls"] }
35-
lazy_static = "1.5.0"
3635
opentelemetry = "0.23.0"
3736
opentelemetry_sdk = { version = "0.23.0", features = ["rt-tokio"] }
3837
opentelemetry-appender-tracing = "0.4.0"

crates/k8s-version/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Changed
8+
9+
- Replace `lazy_static` with `std::cell::LazyCell` ([#827]).
10+
11+
[#827]: https://github.com/stackabletech/operator-rs/pull/827
12+
713
## [0.1.1] - 2024-07-10
814

915
### Changed

crates/k8s-version/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ darling = ["dep:darling"]
1111

1212
[dependencies]
1313
darling = { workspace = true, optional = true }
14-
lazy_static.workspace = true
1514
regex.workspace = true
1615
snafu.workspace = true
1716

crates/k8s-version/src/group.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
use std::{fmt, ops::Deref, str::FromStr};
1+
use std::{fmt, ops::Deref, str::FromStr, sync::LazyLock};
22

3-
use lazy_static::lazy_static;
43
use regex::Regex;
54
use snafu::{ensure, Snafu};
65

76
const MAX_GROUP_LENGTH: usize = 253;
87

9-
lazy_static! {
10-
static ref API_GROUP_REGEX: Regex =
11-
Regex::new(r"^(?:(?:[a-z0-9][a-z0-9-]{0,61}[a-z0-9])\.?)+$")
12-
.expect("failed to compile API group regex");
13-
}
8+
static API_GROUP_REGEX: LazyLock<Regex> = LazyLock::new(|| {
9+
Regex::new(r"^(?:(?:[a-z0-9][a-z0-9-]{0,61}[a-z0-9])\.?)+$")
10+
.expect("failed to compile API group regex")
11+
});
1412

1513
/// Error variants which can be encountered when creating a new [`Group`] from
1614
/// unparsed input.

crates/k8s-version/src/level.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@ use std::{
44
num::ParseIntError,
55
ops::{Add, AddAssign, Sub, SubAssign},
66
str::FromStr,
7+
sync::LazyLock,
78
};
89

9-
use lazy_static::lazy_static;
1010
use regex::Regex;
1111
use snafu::{OptionExt, ResultExt, Snafu};
1212

1313
#[cfg(feature = "darling")]
1414
use darling::FromMeta;
1515

16-
lazy_static! {
17-
static ref LEVEL_REGEX: Regex = Regex::new(r"^(?P<identifier>[a-z]+)(?P<version>\d+)$")
18-
.expect("failed to compile level regex");
19-
}
16+
static LEVEL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
17+
Regex::new(r"^(?P<identifier>[a-z]+)(?P<version>\d+)$").expect("failed to compile level regex")
18+
});
2019

2120
/// Error variants which can be encountered when creating a new [`Level`] from
2221
/// unparsed input.

crates/k8s-version/src/version.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use std::{cmp::Ordering, fmt::Display, num::ParseIntError, str::FromStr};
1+
use std::{cmp::Ordering, fmt::Display, num::ParseIntError, str::FromStr, sync::LazyLock};
22

3-
use lazy_static::lazy_static;
43
use regex::Regex;
54
use snafu::{OptionExt, ResultExt, Snafu};
65

@@ -9,11 +8,10 @@ use darling::FromMeta;
98

109
use crate::{Level, ParseLevelError};
1110

12-
lazy_static! {
13-
static ref VERSION_REGEX: Regex =
14-
Regex::new(r"^v(?P<major>\d+)(?P<level>[a-z0-9][a-z0-9-]{0,60}[a-z0-9])?$")
15-
.expect("failed to compile version regex");
16-
}
11+
static VERSION_REGEX: LazyLock<Regex> = LazyLock::new(|| {
12+
Regex::new(r"^v(?P<major>\d+)(?P<level>[a-z0-9][a-z0-9-]{0,60}[a-z0-9])?$")
13+
.expect("failed to compile version regex")
14+
});
1715

1816
/// Error variants which can be encountered when creating a new [`Version`] from
1917
/// unparsed input.

crates/stackable-operator/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Changed
8+
9+
- BREAKING: Replace `lazy_static` with `std::cell::LazyCell` ([#827]).
10+
11+
[#827]: https://github.com/stackabletech/operator-rs/pull/827
12+
713
## [0.71.0] - 2024-07-29
814

915
### Added

crates/stackable-operator/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ futures.workspace = true
2424
json-patch.workspace = true
2525
k8s-openapi.workspace = true
2626
kube.workspace = true
27-
lazy_static.workspace = true
2827
opentelemetry_sdk.workspace = true
2928
opentelemetry-jaeger.workspace = true
3029
product-config.workspace = true

crates/stackable-operator/src/client.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,15 @@ impl Client {
373373

374374
/// There are four different patch strategies:
375375
/// 1) Apply (<https://kubernetes.io/docs/reference/using-api/api-concepts/#server-side-apply>)
376-
/// Starting from Kubernetes v1.18, you can enable the Server Side Apply feature so that the control plane tracks managed fields for all newly created objects.
376+
/// Starting from Kubernetes v1.18, you can enable the Server Side Apply feature so that the control plane tracks managed fields for all newly created objects.
377377
/// 2) Json (<https://tools.ietf.org/html/rfc6902>):
378-
/// This is supported on crate feature jsonpatch only
378+
/// This is supported on crate feature jsonpatch only
379379
/// 3) Merge (<https://tools.ietf.org/html/rfc7386>):
380-
/// For example, if you want to update a list you have to specify the complete list and update everything
380+
/// For example, if you want to update a list you have to specify the complete list and update everything
381381
/// 4) Strategic (not for CustomResource)
382-
/// With a strategic merge patch, a list is either replaced or merged depending on its patch strategy.
383-
/// The patch strategy is specified by the value of the patchStrategy key in a field tag in the Kubernetes source code.
384-
/// For example, the Containers field of PodSpec struct has a patchStrategy of merge.
382+
/// With a strategic merge patch, a list is either replaced or merged depending on its patch strategy.
383+
/// The patch strategy is specified by the value of the patchStrategy key in a field tag in the Kubernetes source code.
384+
/// For example, the Containers field of PodSpec struct has a patchStrategy of merge.
385385
async fn patch_status<T, S>(
386386
&self,
387387
resource: &T,

crates/stackable-operator/src/commons/listener.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub enum KubernetesTrafficPolicy {
110110
/// 1. It uses a cluster-level policy object (ListenerClass) to define how exactly the exposure works
111111
/// 2. It has a consistent API for reading back the exposed address(es) of the service
112112
/// 3. The Pod must mount a Volume referring to the Listener, which also allows
113-
/// ["sticky" scheduling](DOCS_BASE_URL_PLACEHOLDER/listener-operator/listener#_sticky_scheduling).
113+
/// ["sticky" scheduling](DOCS_BASE_URL_PLACEHOLDER/listener-operator/listener#_sticky_scheduling).
114114
///
115115
/// Learn more in the [Listener documentation](DOCS_BASE_URL_PLACEHOLDER/listener-operator/listener).
116116
#[derive(

crates/stackable-operator/src/commons/opa.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,23 @@
4343
//! assert_eq!(opa_config.document_url(http://github.com/&cluster,%20Some("allow"), OpaApiVersion::V1), "v1/data/test/allow".to_string());
4444
//! assert_eq!(opa_config.full_document_url(http://github.com/&cluster,%20"http://localhost:8081",%20None,%20OpaApiVersion::V1), "http://localhost:8081/v1/data/test".to_string());
4545
//! ```
46+
use std::sync::LazyLock;
47+
4648
use crate::client::{Client, GetApi};
4749
use k8s_openapi::{api::core::v1::ConfigMap, NamespaceResourceScope};
4850
use kube::{Resource, ResourceExt};
49-
use lazy_static::lazy_static;
5051
use regex::Regex;
5152
use schemars::{self, JsonSchema};
5253
use serde::{Deserialize, Serialize};
5354
use snafu::{OptionExt, ResultExt, Snafu};
5455

56+
static DOT_REGEX: LazyLock<Regex> =
57+
LazyLock::new(|| Regex::new("\\.").expect("failed to compile OPA dot regex"));
58+
59+
/// To remove leading slashes from OPA package name (if present)
60+
static LEADING_SLASH_REGEX: LazyLock<Regex> =
61+
LazyLock::new(|| Regex::new("(/*)(.*)").expect("failed to compile OPA leasing slash regex"));
62+
5563
type Result<T, E = Error> = std::result::Result<T, E>;
5664

5765
#[derive(Debug, Snafu)]
@@ -72,11 +80,6 @@ pub enum Error {
7280
},
7381
}
7482

75-
lazy_static! {
76-
static ref DOT_REGEX: Regex = Regex::new("\\.").unwrap();
77-
/// To remove leading slashes from OPA package name (if present)
78-
static ref LEADING_SLASH_REGEX: Regex = Regex::new("(/*)(.*)").unwrap();
79-
}
8083
/// Indicates the OPA API version. This is required to choose the correct
8184
/// path when constructing the OPA urls to query.
8285
pub enum OpaApiVersion {

crates/stackable-operator/src/cpu.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ impl Display for CpuQuantity {
101101
impl FromStr for CpuQuantity {
102102
type Err = Error;
103103

104-
/// Only two formats can be parsed
104+
/// Only two formats can be parsed:
105+
///
105106
/// - {usize}m
106107
/// - {f32}
107-
/// For the float, only milli-precision is supported.
108-
/// Using more precise values will trigger an error, and using any other
109-
/// unit than 'm' or None will also trigger an error.
108+
///
109+
/// For the float, only milli-precision is supported. Using more precise
110+
/// values will trigger an error, and using any other unit than 'm' or None
111+
/// will also trigger an error.
110112
fn from_str(q: &str) -> Result<Self> {
111113
let start_of_unit = q.find(|c: char| c != '.' && !c.is_numeric());
112114
if let Some(start_of_unit) = start_of_unit {

crates/stackable-operator/src/kvp/key.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
use std::{fmt::Display, ops::Deref, str::FromStr};
1+
use std::{fmt::Display, ops::Deref, str::FromStr, sync::LazyLock};
22

3-
use lazy_static::lazy_static;
43
use regex::Regex;
54
use snafu::{ensure, ResultExt, Snafu};
65

76
const KEY_PREFIX_MAX_LEN: usize = 253;
87
const KEY_NAME_MAX_LEN: usize = 63;
98

10-
lazy_static! {
11-
static ref KEY_PREFIX_REGEX: Regex =
12-
Regex::new(r"^[a-zA-Z](\.?[a-zA-Z0-9-])*\.[a-zA-Z]{2,}\.?$").unwrap();
13-
static ref KEY_NAME_REGEX: Regex =
14-
Regex::new(r"^[a-z0-9A-Z]([a-z0-9A-Z-_.]*[a-z0-9A-Z]+)?$").unwrap();
15-
}
9+
// Lazily initialized regular expressions
10+
static KEY_PREFIX_REGEX: LazyLock<Regex> = LazyLock::new(|| {
11+
Regex::new(r"^[a-zA-Z](\.?[a-zA-Z0-9-])*\.[a-zA-Z]{2,}\.?$")
12+
.expect("failed to compile key prefix regex")
13+
});
14+
15+
static KEY_NAME_REGEX: LazyLock<Regex> = LazyLock::new(|| {
16+
Regex::new(r"^[a-z0-9A-Z]([a-z0-9A-Z-_.]*[a-z0-9A-Z]+)?$")
17+
.expect("failed to compile key name regex")
18+
});
1619

1720
/// The error type for key parsing/validation operations.
1821
///

crates/stackable-operator/src/kvp/label/value.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
use std::{fmt::Display, ops::Deref, str::FromStr};
1+
use std::{fmt::Display, ops::Deref, str::FromStr, sync::LazyLock};
22

3-
use lazy_static::lazy_static;
43
use regex::Regex;
54
use snafu::{ensure, Snafu};
65

76
use crate::kvp::Value;
87

98
const LABEL_VALUE_MAX_LEN: usize = 63;
109

11-
lazy_static! {
12-
static ref LABEL_VALUE_REGEX: Regex =
13-
Regex::new(r"^[a-z0-9A-Z]([a-z0-9A-Z-_.]*[a-z0-9A-Z]+)?$").unwrap();
14-
}
10+
// Lazily initialized regular expressions
11+
static LABEL_VALUE_REGEX: LazyLock<Regex> = LazyLock::new(|| {
12+
Regex::new(r"^[a-z0-9A-Z]([a-z0-9A-Z-_.]*[a-z0-9A-Z]+)?$")
13+
.expect("failed to compile value regex")
14+
});
1515

1616
/// The error type for label value parse/validation operations.
1717
#[derive(Debug, PartialEq, Snafu)]

crates/stackable-operator/src/memory.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Utilities for converting Kubernetes quantities to Java heap settings.
22
//! Since Java heap sizes are a subset of Kubernetes quantities, the conversion
3-
//! might lose precision or fail completely.
4-
//! In addition:
3+
//! might lose precision or fail completely. In addition:
4+
//!
55
//! - decimal quantities are not supported ("2G" is invalid)
66
//! - units are case sensitive ("2gi" is invalid)
77
//! - exponential notation is not supported.
@@ -121,12 +121,15 @@ impl Display for BinaryMultiple {
121121
}
122122

123123
/// Convert a (memory) [`Quantity`] to Java heap settings.
124+
///
124125
/// Quantities are usually passed on to container resources while Java heap
125-
/// sizes need to be scaled accordingly.
126-
/// This implements a very simple heuristic to ensure that:
126+
/// sizes need to be scaled accordingly. This implements a very simple heuristic
127+
/// to ensure that:
128+
///
127129
/// - the quantity unit has been mapped to a java supported heap unit. Java only
128130
/// supports up to Gibibytes while K8S quantities can be expressed in Exbibytes.
129131
/// - the heap size has a non-zero value.
132+
///
130133
/// Fails if it can't enforce the above restrictions.
131134
#[deprecated(
132135
since = "0.33.0",
@@ -148,15 +151,17 @@ pub fn to_java_heap(q: &Quantity, factor: f32) -> Result<String> {
148151
}
149152

150153
/// Convert a (memory) [`Quantity`] to a raw Java heap value of the desired `target_unit`.
154+
///
151155
/// Quantities are usually passed on to container resources while Java heap
152-
/// sizes need to be scaled accordingly.
153-
/// The raw heap value is converted to the specified `target_unit` (this conversion
154-
/// is done even if specified a unit greater that Gibibytes. It is not recommended to scale
155-
/// to anything bigger than Gibibytes.
156-
/// This implements a very simple heuristic to ensure that:
156+
/// sizes need to be scaled accordingly. The raw heap value is converted to the
157+
/// specified `target_unit` (this conversion is done even if specified a unit
158+
/// greater that Gibibytes. It is not recommended to scale to anything bigger
159+
/// than Gibibytes. This implements a very simple heuristic to ensure that:
160+
///
157161
/// - the quantity unit has been mapped to a java supported heap unit. Java only
158162
/// supports up to Gibibytes while K8S quantities can be expressed in Exbibytes.
159163
/// - the heap size has a non-zero value.
164+
///
160165
/// Fails if it can't enforce the above restrictions.
161166
#[deprecated(
162167
since = "0.33.0",

crates/stackable-operator/src/status/condition/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -290,16 +290,20 @@ impl ClusterConditionSet {
290290
self.conditions[index] = Some(condition);
291291
}
292292

293-
/// Merges two [`ClusterConditionSet`]s. The condition_combiner implements the strategy used to
294-
/// merge two conditions of the same `type_`.
293+
/// Merges two [`ClusterConditionSet`]s.
294+
///
295+
/// The condition_combiner implements the strategy used to merge two
296+
/// conditions of the same `type_`.
295297
///
296298
/// # Arguments
297299
///
298300
/// * `other` - The [`ClusterConditionSet`] to be merged
299-
/// * `condition_combiner` - This is either be `update_message` or `update_timestamps`. The
300-
/// `update_message` is used to concatenate messages of the same [`ClusterConditionStatus`] and
301-
/// the same [`ClusterConditionType`]. The `update_timestamps` is required to merge the old
302-
/// cluster status with the new one and update transition timestamps correctly.
301+
/// * `condition_combiner` - This is either be `update_message` or
302+
/// `update_timestamps`. The `update_message` is used to concatenate
303+
/// messages of the same [`ClusterConditionStatus`] and the same
304+
/// [`ClusterConditionType`]. The `update_timestamps` is required to merge
305+
/// the old cluster status with the new one and update transition
306+
/// timestamps correctly.
303307
fn merge(
304308
self,
305309
other: ClusterConditionSet,
@@ -361,7 +365,7 @@ fn update_timestamps(
361365
/// A condition combiner strategy with the following properties:
362366
/// 1. It preserves the condition with the highest status.
363367
/// 2. It joins the previous messages to the current one if both conditions
364-
/// have the same status.
368+
/// have the same status.
365369
fn update_message(
366370
old_condition: ClusterCondition,
367371
new_condition: ClusterCondition,

0 commit comments

Comments
 (0)