Skip to content

Commit

Permalink
Bump MSRV to 1.80.
Browse files Browse the repository at this point in the history
This is, at time of writing, the "stable minus two releases" that Janus
supports. Also, clean up a few uses of OnceLock -- mostly to replace
with the simpler LazyLock stabilized in 1.80, in one place replacing it
with an async mutex as neither OnceLock nor LazyLock were appropriate as
the initializing function would be async.
  • Loading branch information
branlwyd committed Nov 27, 2024
1 parent 217ecde commit bf5d6e9
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ edition = "2021"
homepage = "https://divviup.org"
license = "MPL-2.0"
repository = "https://github.com/divviup/janus"
rust-version = "1.77.0"
rust-version = "1.80.0"
version = "0.8.0-prerelease-1"

[workspace.dependencies]
Expand Down
39 changes: 21 additions & 18 deletions aggregator/src/binaries/janus_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ use serde::{Deserialize, Serialize};
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
sync::{Arc, OnceLock},
sync::Arc,
};
use tokio::{
fs,
runtime::{self, Runtime},
sync::Mutex,
};
use tracing::{debug, info};
use url::Url;
Expand Down Expand Up @@ -510,8 +511,7 @@ async fn fetch_datastore_keys(
secret_data_key, namespace, secret_name,
);

let secrets_api: kube::Api<Secret> =
kube::Api::namespaced(kube_client.get().await?.clone(), namespace);
let secrets_api: kube::Api<Secret> = kube::Api::namespaced(kube_client.get().await?, namespace);

let secret = secrets_api
.get(secret_name)
Expand Down Expand Up @@ -542,7 +542,7 @@ async fn create_datastore_key(
"Creating datastore key"
);
let secrets_api: kube::Api<Secret> =
kube::Api::namespaced(kube_client.get().await?.clone(), k8s_namespace);
kube::Api::namespaced(kube_client.get().await?, k8s_namespace);

// Generate a random datastore key & encode it into unpadded base64 as will be expected by
// consumers of the secret we are about to write.
Expand Down Expand Up @@ -700,40 +700,43 @@ impl BinaryConfig for ConfigFile {

/// A wrapper around [`kube::Client`] adding lazy initialization.
struct LazyKubeClient {
lock: OnceLock<kube::Client>,
lock: Mutex<Option<kube::Client>>,
}

impl LazyKubeClient {
fn new() -> Self {
Self {
lock: OnceLock::new(),
lock: Mutex::default(),
}
}

/// Return a reference to a client, constructing a client from the default inferred
/// configuration if it has not been done yet. This will use the local kubeconfig file if
/// present, use in-cluster environment variables if present, or fail.
async fn get(&self) -> Result<&kube::Client> {
if let Some(client) = self.lock.get() {
return Ok(client);
async fn get(&self) -> Result<kube::Client> {
let mut guard = self.lock.lock().await;
match guard.as_ref() {
Some(kube_client) => Ok(kube_client.clone()),
None => {
let kube_client = kube::Client::try_default()
.await
.context("couldn't load Kubernetes configuration")?;
*guard = Some(kube_client.clone());
Ok(kube_client)
}
}
let _ = self.lock.set(
kube::Client::try_default()
.await
.context("couldn't load Kubernetes configuration")?,
);
Ok(self.lock.get().unwrap())
}
}

impl From<kube::Client> for LazyKubeClient {
fn from(value: kube::Client) -> Self {
fn from(kube_client: kube::Client) -> Self {
Self {
lock: OnceLock::from(value),
lock: Mutex::new(Some(kube_client)),
}
}
}


#[cfg(test)]
mod tests {
use crate::{
Expand Down Expand Up @@ -823,7 +826,7 @@ mod tests {
expected_datastore_keys
);
// Shouldn't have set up a kube Client for this, since no namespace was given.
assert!(empty_kube_client.lock.get().is_none());
assert!(empty_kube_client.lock.lock().await.is_none());

// Keys not provided at command line, present in k8s
let common_options = CommonBinaryOptions::default();
Expand Down
9 changes: 4 additions & 5 deletions aggregator_api/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rand::random;
use ring::digest::{digest, SHA256};
use std::{
str::FromStr,
sync::{Arc, OnceLock},
sync::{Arc, LazyLock},
unreachable,
};
use trillium::{Conn, Status};
Expand All @@ -36,9 +36,8 @@ pub(super) async fn get_config(
_: &mut Conn,
State(config): State<Arc<Config>>,
) -> Json<AggregatorApiConfig> {
static VERSION: OnceLock<String> = OnceLock::new();
let software_version =
VERSION.get_or_init(|| format!("{}-{}", env!("CARGO_PKG_VERSION"), git_revision()));
static VERSION: LazyLock<String> =
LazyLock::new(|| format!("{}-{}", env!("CARGO_PKG_VERSION"), git_revision()));

Json(AggregatorApiConfig {
protocol: "DAP-09",
Expand All @@ -61,7 +60,7 @@ pub(super) async fn get_config(
"PureDpDiscreteLaplace",
],
software_name: "Janus",
software_version,
software_version: &VERSION,
})
}

Expand Down
8 changes: 4 additions & 4 deletions aggregator_core/src/taskprov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::{
de::{self, Visitor},
Deserialize, Serialize, Serializer,
};
use std::{fmt, str::FromStr, sync::OnceLock};
use std::{fmt, str::FromStr, sync::LazyLock};
use url::Url;

#[derive(Educe, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -131,8 +131,7 @@ pub struct PeerAggregator {
///
/// [1]: https://www.ietf.org/archive/id/draft-wang-ppm-dap-taskprov-04.html#name-deriving-the-vdaf-verificat
fn taskprov_salt() -> &'static Salt {
static SALT: OnceLock<Salt> = OnceLock::new();
SALT.get_or_init(|| {
static SALT: LazyLock<Salt> = LazyLock::new(|| {
Salt::new(
HKDF_SHA256,
&[
Expand All @@ -141,7 +140,8 @@ fn taskprov_salt() -> &'static Salt {
0x72, 0x3a, 0xf, 0xfe,
],
)
})
});
&SALT
}

impl PeerAggregator {
Expand Down
10 changes: 4 additions & 6 deletions core/src/auth_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ring::{
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use std::{
str::{self, FromStr},
sync::OnceLock,
sync::LazyLock,
};

/// HTTP header where auth tokens are provided in messages between participants.
Expand Down Expand Up @@ -242,11 +242,9 @@ impl BearerToken {
///
/// [1]: https://datatracker.ietf.org/doc/html/rfc6750#section-2.1
fn validate(value: &str) -> Result<(), anyhow::Error> {
static REGEX: OnceLock<Regex> = OnceLock::new();

let regex = REGEX.get_or_init(|| Regex::new("^[-A-Za-z0-9._~+/]+=*$").unwrap());

if regex.is_match(value) {
static REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new("^[-A-Za-z0-9._~+/]+=*$").unwrap());
if REGEX.is_match(value) {
Ok(())
} else {
Err(anyhow::anyhow!("bearer token has invalid format"))
Expand Down
9 changes: 4 additions & 5 deletions integration_tests/tests/integration/in_cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ mod rate_limits {
use std::{
env,
fs::File,
sync::{Arc, OnceLock},
sync::{Arc, LazyLock},
time::Duration,
};
use tokio::sync::Semaphore;
Expand All @@ -687,14 +687,13 @@ mod rate_limits {

impl TestConfig {
fn load() -> &'static Self {
static CONFIG: OnceLock<TestConfig> = OnceLock::new();

CONFIG.get_or_init(|| {
static CONFIG: LazyLock<TestConfig> = LazyLock::new(|| {
serde_json::from_reader(
File::open(env::var("JANUS_E2E_RATE_LIMIT_TEST_CONFIG").unwrap()).unwrap(),
)
.unwrap()
})
});
&CONFIG
}
}

Expand Down
7 changes: 3 additions & 4 deletions integration_tests/tests/integration/simulation/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
borrow::Cow,
sync::{Arc, Mutex, OnceLock},
sync::{Arc, LazyLock, Mutex},
};

use regex::bytes::Regex;
Expand Down Expand Up @@ -143,11 +143,10 @@ impl<H: Handler> InspectHandler<H> {
}
if conn.path().ends_with("/aggregate_shares") {
inspect_response_body(&mut conn, |bytes| {
static ONCE: OnceLock<Regex> = OnceLock::new();
let batch_mismatch_regex = ONCE.get_or_init(|| {
static REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new("urn:ietf:params:ppm:dap:error:batchMismatch").unwrap()
});
if batch_mismatch_regex.is_match(bytes) {
if REGEX.is_match(bytes) {
error!("batch mismatch response");
*self.failure.lock().unwrap() = true;
}
Expand Down

0 comments on commit bf5d6e9

Please sign in to comment.