uses OnceCell for lazy endpoint initialization in quic-client (#31149)

RwLock<Option<...>> lacks the api and adds unnecessary overhead for lazy
initialization. OnceCell instead provides the intended api for this purpose.
This commit is contained in:
behzad nouri 2023-04-11 19:53:25 +00:00 committed by GitHub
parent 965dd37924
commit 557e4c47e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 7 additions and 23 deletions

View File

@ -35,7 +35,7 @@ use {
thread, thread,
}, },
thiserror::Error, thiserror::Error,
tokio::{sync::RwLock, time::timeout}, tokio::{sync::OnceCell, time::timeout},
}; };
struct SkipServerVerification; struct SkipServerVerification;
@ -67,7 +67,7 @@ pub struct QuicClientCertificate {
/// A lazy-initialized Quic Endpoint /// A lazy-initialized Quic Endpoint
pub struct QuicLazyInitializedEndpoint { pub struct QuicLazyInitializedEndpoint {
endpoint: RwLock<Option<Arc<Endpoint>>>, endpoint: OnceCell<Arc<Endpoint>>,
client_certificate: Arc<QuicClientCertificate>, client_certificate: Arc<QuicClientCertificate>,
client_endpoint: Option<Endpoint>, client_endpoint: Option<Endpoint>,
} }
@ -94,7 +94,7 @@ impl QuicLazyInitializedEndpoint {
client_endpoint: Option<Endpoint>, client_endpoint: Option<Endpoint>,
) -> Self { ) -> Self {
Self { Self {
endpoint: RwLock::new(None), endpoint: OnceCell::<Arc<Endpoint>>::new(),
client_certificate, client_certificate,
client_endpoint, client_endpoint,
} }
@ -139,26 +139,10 @@ impl QuicLazyInitializedEndpoint {
} }
async fn get_endpoint(&self) -> Arc<Endpoint> { async fn get_endpoint(&self) -> Arc<Endpoint> {
let lock = self.endpoint.read().await; self.endpoint
let endpoint = lock.as_ref(); .get_or_init(|| async { Arc::new(self.create_endpoint()) })
.await
match endpoint { .clone()
Some(endpoint) => endpoint.clone(),
None => {
drop(lock);
let mut lock = self.endpoint.write().await;
let endpoint = lock.as_ref();
match endpoint {
Some(endpoint) => endpoint.clone(),
None => {
let connection = Arc::new(self.create_endpoint());
*lock = Some(connection.clone());
connection
}
}
}
}
} }
} }