Skip to content

Commit 385a3fe

Browse files
committed
clippy: Disallow lock and instant types from std (#1458)
We use `parking_lot` locks throughout our code. This change disallows the introduction of std::sync's locks. This change also enforces the use of `tokio::time::Instant`, which allows for a mockable time source in tests. Signed-off-by: Oliver Gould <[email protected]> (cherry picked from commit 8aa474e) Signed-off-by: Oliver Gould <[email protected]>
1 parent 594e860 commit 385a3fe

File tree

81 files changed

+475
-205
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+475
-205
lines changed

.clippy.toml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
type-complexity-threshold = 500
22
disallowed-methods = [
3-
# mutating environment variables in a multi-threaded context can
3+
# Mutating environment variables in a multi-threaded context can
44
# cause data races.
55
# see https://github.com/rust-lang/rust/issues/90308 for details.
66
"std::env::set_var",
77
"std::env::remove_var",
88

9-
# Avoid instances of https://github.com/rust-lang/rust/issues/86470
10-
"std::time::Instant::duration_since",
11-
"std::time::Instant::elapsed",
12-
# Clippy doesn't let us ban std::time::Instant::sub, but it knows what it did.
9+
# Avoid instances of https://github.com/rust-lang/rust/issues/86470 until tokio/tokio#4461 is
10+
# available.
11+
"tokio::time::Instant::duration_since",
12+
"tokio::time::Instant::elapsed",
13+
# Clippy doesn't let us ban tokio::time::Instant::sub, but it knows what it did.
14+
]
15+
disallowed-types = [
16+
# Use parking_lot instead.
17+
"std::sync::Mutex",
18+
"std::sync::RwLock",
19+
20+
# Use tokio::time::Instant instead.
21+
"std::time::Instant",
1322
]

Cargo.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,7 @@ dependencies = [
786786
"linkerd-metrics",
787787
"linkerd-tracing",
788788
"linkerd2-proxy-api",
789+
"parking_lot 0.12.0",
789790
"regex",
790791
"socket2 0.4.4",
791792
"tokio",
@@ -835,6 +836,7 @@ dependencies = [
835836
"linkerd-app-core",
836837
"linkerd-identity",
837838
"linkerd-io",
839+
"parking_lot 0.12.0",
838840
"regex",
839841
"thiserror",
840842
"tokio",
@@ -982,6 +984,7 @@ dependencies = [
982984
"linkerd-stack",
983985
"parking_lot 0.12.0",
984986
"pin-project",
987+
"tokio",
985988
"tower",
986989
"tracing",
987990
]
@@ -1326,6 +1329,7 @@ dependencies = [
13261329
"futures",
13271330
"linkerd-error",
13281331
"linkerd-tracing",
1332+
"parking_lot 0.12.0",
13291333
"pin-project",
13301334
"thiserror",
13311335
"tokio",
@@ -1464,6 +1468,7 @@ dependencies = [
14641468
"linkerd-stack",
14651469
"parking_lot 0.12.0",
14661470
"pin-project",
1471+
"tokio",
14671472
"tracing",
14681473
]
14691474

hyper-balance/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
1+
#![deny(
2+
warnings,
3+
rust_2018_idioms,
4+
clippy::disallowed_method,
5+
clippy::disallowed_type
6+
)]
27
#![forbid(unsafe_code)]
38

49
use hyper::body::HttpBody;

linkerd/addr/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
1+
#![deny(
2+
warnings,
3+
rust_2018_idioms,
4+
clippy::disallowed_method,
5+
clippy::disallowed_type
6+
)]
27
#![forbid(unsafe_code)]
38
use linkerd_dns_name::Name;
49
use std::{

linkerd/app/admin/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
1+
#![deny(
2+
warnings,
3+
rust_2018_idioms,
4+
clippy::disallowed_method,
5+
clippy::disallowed_type
6+
)]
27
#![forbid(unsafe_code)]
38

49
mod server;

linkerd/app/core/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
//! - Tap
88
//! - Metric labeling
99
10-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
10+
#![deny(
11+
warnings,
12+
rust_2018_idioms,
13+
clippy::disallowed_method,
14+
clippy::disallowed_type
15+
)]
1116
#![forbid(unsafe_code)]
1217

1318
pub use drain;

linkerd/app/gateway/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
1+
#![deny(
2+
warnings,
3+
rust_2018_idioms,
4+
clippy::disallowed_method,
5+
clippy::disallowed_type
6+
)]
27
#![forbid(unsafe_code)]
38

49
mod gateway;

linkerd/app/inbound/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
//! The inbound proxy is responsible for terminating traffic from other network
44
//! endpoints inbound to the local application.
55
6-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
6+
#![deny(
7+
warnings,
8+
rust_2018_idioms,
9+
clippy::disallowed_method,
10+
clippy::disallowed_type
11+
)]
712
#![forbid(unsafe_code)]
813

914
mod accept;

linkerd/app/integration/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ linkerd-metrics = { path = "../../metrics", features = ["test_util"] }
2929
linkerd2-proxy-api = { version = "0.3", features = ["destination", "arbitrary"] }
3030
linkerd-app-test = { path = "../test" }
3131
linkerd-tracing = { path = "../../tracing" }
32+
parking_lot = "0.12"
3233
regex = "1"
3334
socket2 = "0.4"
3435
tokio = { version = "1", features = ["io-util", "net", "rt", "macros"] }

linkerd/app/integration/src/client.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use linkerd_app_core::proxy::http::trace;
3-
use std::io;
4-
use std::sync::{Arc, Mutex};
3+
use parking_lot::Mutex;
4+
use std::{io, sync::Arc};
55
use tokio::net::TcpStream;
66
use tokio::sync::{mpsc, oneshot};
77
use tokio::task::JoinHandle;
@@ -315,7 +315,6 @@ impl tower::Service<hyper::Uri> for Conn {
315315
let running = self
316316
.running
317317
.lock()
318-
.unwrap()
319318
.take()
320319
.expect("test client cannot connect twice");
321320
Box::pin(async move {

linkerd/app/integration/src/controller.rs

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use super::*;
33
use linkerd2_proxy_api::destination as pb;
44
use linkerd2_proxy_api::net;
55
use linkerd_app_core::proxy::http::trace;
6+
use parking_lot::Mutex;
67
use std::collections::{HashMap, VecDeque};
78
use std::net::IpAddr;
89
use std::ops::{Bound, RangeBounds};
9-
use std::sync::{Arc, Mutex};
10+
use std::sync::Arc;
1011
use tokio::sync::mpsc;
1112
use tokio_stream::wrappers::UnboundedReceiverStream;
1213
use tonic as grpc;
@@ -86,7 +87,6 @@ impl Controller {
8687
};
8788
self.expect_dst_calls
8889
.lock()
89-
.unwrap()
9090
.push_back(Dst::Call(dst, Ok(rx)));
9191
DstSender(tx)
9292
}
@@ -108,12 +108,11 @@ impl Controller {
108108
};
109109
self.expect_dst_calls
110110
.lock()
111-
.unwrap()
112111
.push_back(Dst::Call(dst, Err(status)));
113112
}
114113

115114
pub fn no_more_destinations(&self) {
116-
self.expect_dst_calls.lock().unwrap().push_back(Dst::Done);
115+
self.expect_dst_calls.lock().push_back(Dst::Done);
117116
}
118117

119118
pub async fn delay_listen<F>(self, f: F) -> Listening
@@ -148,10 +147,7 @@ impl Controller {
148147
path,
149148
..Default::default()
150149
};
151-
self.expect_profile_calls
152-
.lock()
153-
.unwrap()
154-
.push_back((dst, rx));
150+
self.expect_profile_calls.lock().push_back((dst, rx));
155151
ProfileSender(tx)
156152
}
157153

@@ -232,52 +228,51 @@ impl pb::destination_server::Destination for Controller {
232228
let _e = span.enter();
233229
tracing::debug!(request = ?req.get_ref(), "received");
234230

235-
if let Ok(mut calls) = self.expect_dst_calls.lock() {
236-
if self.unordered {
237-
let mut calls_next: VecDeque<Dst> = VecDeque::new();
238-
if calls.is_empty() {
239-
tracing::warn!("calls exhausted");
240-
}
241-
while let Some(call) = calls.pop_front() {
242-
if let Dst::Call(dst, updates) = call {
243-
tracing::debug!(?dst, "checking");
244-
if &dst == req.get_ref() {
245-
tracing::info!(?dst, ?updates, "found request");
246-
calls_next.extend(calls.drain(..));
247-
*calls = calls_next;
248-
return updates.map(grpc::Response::new);
249-
}
250-
251-
calls_next.push_back(Dst::Call(dst, updates));
252-
}
253-
}
254-
255-
tracing::warn!(remaining = calls_next.len(), "missed");
256-
*calls = calls_next;
257-
return Err(grpc_unexpected_request());
231+
let mut calls = self.expect_dst_calls.lock();
232+
if self.unordered {
233+
let mut calls_next: VecDeque<Dst> = VecDeque::new();
234+
if calls.is_empty() {
235+
tracing::warn!("calls exhausted");
258236
}
259-
260-
match calls.pop_front() {
261-
Some(Dst::Call(dst, updates)) => {
262-
tracing::debug!(?dst, "checking next call");
237+
while let Some(call) = calls.pop_front() {
238+
if let Dst::Call(dst, updates) = call {
239+
tracing::debug!(?dst, "checking");
263240
if &dst == req.get_ref() {
264241
tracing::info!(?dst, ?updates, "found request");
242+
calls_next.extend(calls.drain(..));
243+
*calls = calls_next;
265244
return updates.map(grpc::Response::new);
266245
}
267246

268-
tracing::warn!(?dst, ?updates, "request does not match");
269-
let msg = format!(
270-
"expected get call for {:?} but got get call for {:?}",
271-
dst, req
272-
);
273-
calls.push_front(Dst::Call(dst, updates));
274-
return Err(grpc::Status::new(grpc::Code::Unavailable, msg));
247+
calls_next.push_back(Dst::Call(dst, updates));
275248
}
276-
Some(Dst::Done) => {
277-
panic!("unit test controller expects no more Destination.Get calls")
249+
}
250+
251+
tracing::warn!(remaining = calls_next.len(), "missed");
252+
*calls = calls_next;
253+
return Err(grpc_unexpected_request());
254+
}
255+
256+
match calls.pop_front() {
257+
Some(Dst::Call(dst, updates)) => {
258+
tracing::debug!(?dst, "checking next call");
259+
if &dst == req.get_ref() {
260+
tracing::info!(?dst, ?updates, "found request");
261+
return updates.map(grpc::Response::new);
278262
}
279-
_ => {}
263+
264+
tracing::warn!(?dst, ?updates, "request does not match");
265+
let msg = format!(
266+
"expected get call for {:?} but got get call for {:?}",
267+
dst, req
268+
);
269+
calls.push_front(Dst::Call(dst, updates));
270+
return Err(grpc::Status::new(grpc::Code::Unavailable, msg));
280271
}
272+
Some(Dst::Done) => {
273+
panic!("unit test controller expects no more Destination.Get calls")
274+
}
275+
_ => {}
281276
}
282277

283278
Err(grpc_no_results())
@@ -296,18 +291,17 @@ impl pb::destination_server::Destination for Controller {
296291
);
297292
let _e = span.enter();
298293
tracing::debug!(request = ?req.get_ref(), "received");
299-
if let Ok(mut calls) = self.expect_profile_calls.lock() {
300-
if let Some((dst, profile)) = calls.pop_front() {
301-
tracing::debug!(?dst, "checking next call");
302-
if &dst == req.get_ref() {
303-
tracing::info!(?dst, ?profile, "found request");
304-
return Ok(grpc::Response::new(Box::pin(profile)));
305-
}
306-
307-
tracing::warn!(?dst, ?profile, "request does not match");
308-
calls.push_front((dst, profile));
309-
return Err(grpc_unexpected_request());
294+
let mut calls = self.expect_profile_calls.lock();
295+
if let Some((dst, profile)) = calls.pop_front() {
296+
tracing::debug!(?dst, "checking next call");
297+
if &dst == req.get_ref() {
298+
tracing::info!(?dst, ?profile, "found request");
299+
return Ok(grpc::Response::new(Box::pin(profile)));
310300
}
301+
302+
tracing::warn!(?dst, ?profile, "request does not match");
303+
calls.push_front((dst, profile));
304+
return Err(grpc_unexpected_request());
311305
}
312306

313307
Err(grpc_no_results())

linkerd/app/integration/src/identity.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use super::*;
2+
use parking_lot::Mutex;
23
use std::{
34
collections::VecDeque,
45
fs, io,
56
path::{Path, PathBuf},
6-
sync::{Arc, Mutex},
7+
sync::Arc,
78
time::{Duration, SystemTime},
89
};
910

@@ -198,7 +199,7 @@ impl Controller {
198199
.map_err(|e| grpc::Status::new(grpc::Code::Internal, format!("{}", e)));
199200
Box::pin(fut)
200201
});
201-
self.expect_calls.lock().unwrap().push_back(func);
202+
self.expect_calls.lock().push_back(func);
202203
self
203204
}
204205

@@ -222,7 +223,6 @@ impl pb::identity_server::Identity for Controller {
222223
let f = self
223224
.expect_calls
224225
.lock()
225-
.unwrap()
226226
.pop_front()
227227
.map(|mut f| f(req.into_inner()));
228228
if let Some(f) = f {

linkerd/app/integration/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! Shared infrastructure for integration tests
22
3-
#![deny(warnings, rust_2018_idioms, clippy::disallowed_method)]
3+
#![deny(
4+
warnings,
5+
rust_2018_idioms,
6+
clippy::disallowed_method,
7+
clippy::disallowed_type
8+
)]
49
#![forbid(unsafe_code)]
510

611
mod test_env;
@@ -66,8 +71,8 @@ macro_rules! assert_eventually {
6671
($cond:expr, retries: $retries:expr, $($arg:tt)+) => {
6772
{
6873
use std::{env, u64};
69-
use std::time::{Instant, Duration};
7074
use std::str::FromStr;
75+
use tokio::time::{Instant, Duration};
7176
use tracing::Instrument as _;
7277
// TODO: don't do this *every* time eventually is called (lazy_static?)
7378
let patience = env::var($crate::ENV_TEST_PATIENCE_MS).ok()

linkerd/app/integration/src/metrics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ impl MetricMatch {
195195
#[track_caller]
196196
pub async fn assert_in(&self, client: &crate::client::Client) {
197197
use std::str::FromStr;
198-
use std::time::{Duration, Instant};
199198
use std::{env, u64};
199+
use tokio::time::{Duration, Instant};
200200
use tracing::Instrument as _;
201201
const MAX_RETRIES: usize = 5;
202202
// TODO: don't do this *every* time eventually is called (lazy_static?)

0 commit comments

Comments
 (0)