Erase SHARDS const generic from Sender

This commit is contained in:
asonix 2024-01-28 12:55:48 -06:00
parent 7b5db89dc8
commit a9c8dae84b

View file

@ -16,38 +16,46 @@ use rustls::sign::CertifiedKey;
/// contention, leading to faster reads but more writes per call to `update`.
pub fn channel<const SHARDS: usize>(
initial: CertifiedKey,
) -> (ChannelSender<SHARDS>, Arc<ChannelResolver<SHARDS>>) {
) -> (ChannelSender, Arc<ChannelResolver<SHARDS>>) {
let resolver = Arc::new(ChannelResolver::<SHARDS>::new(initial));
(
ChannelSender {
inner: Arc::clone(&resolver),
},
resolver,
)
let cloned_resolver = Arc::clone(&resolver);
let inner = cloned_resolver as Arc<ErasedChannelResolver>;
(ChannelSender { inner }, resolver)
}
/// The Send half of the channel. This is used for updating the server with new keys
#[derive(Clone)]
pub struct ChannelSender<const SHARDS: usize> {
inner: Arc<ChannelResolver<SHARDS>>,
pub struct ChannelSender {
inner: Arc<ErasedChannelResolver>,
}
mod sealed {
use std::sync::{atomic::AtomicU64, Arc, RwLock};
use rustls::sign::CertifiedKey;
pub struct ChannelResolverInner<L: ?Sized> {
pub(super) locks: L,
}
pub struct Shard {
pub(super) generation: AtomicU64,
pub(super) lock: RwLock<Arc<CertifiedKey>>,
}
}
// The Receive half of the channel. This is registerd with rustls to provide the server with keys
pub struct ChannelResolver<const SHARDS: usize> {
locks: [Shard; SHARDS],
}
struct Shard {
generation: AtomicU64,
lock: RwLock<Arc<CertifiedKey>>,
}
pub type ChannelResolver<const SHARDS: usize> =
sealed::ChannelResolverInner<[sealed::Shard; SHARDS]>;
type ErasedChannelResolver = sealed::ChannelResolverInner<[sealed::Shard]>;
thread_local! {
static LOCAL_KEY: OnceCell<RefCell<(u64, Arc<CertifiedKey>)>> = OnceCell::new();
}
impl Shard {
impl sealed::Shard {
fn new(key: CertifiedKey) -> Self {
Self {
generation: AtomicU64::new(0),
@ -96,23 +104,19 @@ impl Shard {
}
}
impl<const SHARDS: usize> ChannelSender<SHARDS> {
impl ChannelSender {
/// Update the key in the channel
pub fn update(&self, key: CertifiedKey) {
self.inner.update(key);
for lock in &self.inner.locks {
lock.update(key.clone());
}
}
}
impl<const SHARDS: usize> ChannelResolver<SHARDS> {
fn new(key: CertifiedKey) -> Self {
Self {
locks: [(); SHARDS].map(|()| Shard::new(key.clone())),
}
}
fn update(&self, key: CertifiedKey) {
for lock in &self.locks {
lock.update(key.clone());
locks: [(); SHARDS].map(|()| sealed::Shard::new(key.clone())),
}
}