Erase SHARDS const generic from Sender
This commit is contained in:
parent
7b5db89dc8
commit
a9c8dae84b
1 changed files with 31 additions and 27 deletions
58
src/lib.rs
58
src/lib.rs
|
@ -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())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue