Skip to content

Commit 8aa474e

Browse files
authored
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]>
1 parent bffdb1a commit 8aa474e

File tree

89 files changed

+514
-210
lines changed

Some content is hidden

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

89 files changed

+514
-210
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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ dependencies = [
917917
"linkerd-metrics",
918918
"linkerd-tracing",
919919
"linkerd2-proxy-api",
920+
"parking_lot 0.12.0",
920921
"regex",
921922
"rustls-pemfile",
922923
"socket2 0.4.4",
@@ -968,6 +969,7 @@ dependencies = [
968969
"linkerd-app-core",
969970
"linkerd-identity",
970971
"linkerd-io",
972+
"parking_lot 0.12.0",
971973
"regex",
972974
"thiserror",
973975
"tokio",
@@ -1090,6 +1092,7 @@ dependencies = [
10901092
"linkerd-tls",
10911093
"linkerd-tracing",
10921094
"pin-project",
1095+
"tokio",
10931096
"tracing",
10941097
]
10951098

@@ -1131,6 +1134,7 @@ dependencies = [
11311134
"linkerd-stack",
11321135
"parking_lot 0.12.0",
11331136
"pin-project",
1137+
"tokio",
11341138
"tower",
11351139
"tracing",
11361140
]
@@ -1529,6 +1533,7 @@ dependencies = [
15291533
"futures",
15301534
"linkerd-error",
15311535
"linkerd-tracing",
1536+
"parking_lot 0.12.0",
15321537
"pin-project",
15331538
"thiserror",
15341539
"tokio",
@@ -1669,6 +1674,7 @@ dependencies = [
16691674
"linkerd-stack",
16701675
"parking_lot 0.12.0",
16711676
"pin-project",
1677+
"tokio",
16721678
"tracing",
16731679
]
16741680

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
@@ -31,6 +31,7 @@ linkerd-metrics = { path = "../../metrics", features = ["test_util"] }
3131
linkerd2-proxy-api = { version = "0.3", features = ["destination", "arbitrary"] }
3232
linkerd-app-test = { path = "../test" }
3333
linkerd-tracing = { path = "../../tracing" }
34+
parking_lot = "0.12"
3435
regex = "1"
3536
socket2 = "0.4"
3637
tokio = { version = "1", features = ["io-util", "net", "rt", "macros"] }

linkerd/app/integration/src/client.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use super::*;
22
use linkerd_app_core::proxy::http::trace;
3+
use parking_lot::Mutex;
34
use std::io;
4-
use std::{
5-
convert::TryFrom,
6-
sync::{Arc, Mutex},
7-
};
5+
use std::{convert::TryFrom, sync::Arc};
86
use tokio::net::TcpStream;
97
use tokio::sync::{mpsc, oneshot};
108
use tokio::task::JoinHandle;
@@ -315,7 +313,6 @@ impl tower::Service<hyper::Uri> for Conn {
315313
let running = self
316314
.running
317315
.lock()
318-
.unwrap()
319316
.take()
320317
.expect("test client cannot connect twice");
321318
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

@@ -206,7 +207,7 @@ impl Controller {
206207
.map_err(|e| grpc::Status::new(grpc::Code::Internal, format!("{}", e)));
207208
Box::pin(fut)
208209
});
209-
self.expect_calls.lock().unwrap().push_back(func);
210+
self.expect_calls.lock().push_back(func);
210211
self
211212
}
212213

@@ -230,7 +231,6 @@ impl pb::identity_server::Identity for Controller {
230231
let f = self
231232
.expect_calls
232233
.lock()
233-
.unwrap()
234234
.pop_front()
235235
.map(|mut f| f(req.into_inner()));
236236
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()

0 commit comments

Comments
 (0)