pub struct RefreshScheduler {
closures: Mutex<HashMap<String, Arc<RegisteredClosures>>>,
tables: Mutex<ReducerTables>,
notifiers: Mutex<HashMap<String, Arc<Notify>>>,
}Fields§
§closures: Mutex<HashMap<String, Arc<RegisteredClosures>>>§tables: Mutex<ReducerTables>§notifiers: Mutex<HashMap<String, Arc<Notify>>>Implementations§
Source§impl RefreshScheduler
impl RefreshScheduler
pub fn new() -> Self
Sourcepub async fn register(
&self,
credential_id: impl Into<String>,
is_fresh: impl Fn() -> Pin<Box<dyn Future<Output = bool> + Send + 'static>> + Send + Sync + 'static,
refresh: impl Fn() -> Pin<Box<dyn Future<Output = Result<(), RefreshErrorKind>> + Send + 'static>> + Send + Sync + 'static,
)
pub async fn register( &self, credential_id: impl Into<String>, is_fresh: impl Fn() -> Pin<Box<dyn Future<Output = bool> + Send + 'static>> + Send + Sync + 'static, refresh: impl Fn() -> Pin<Box<dyn Future<Output = Result<(), RefreshErrorKind>> + Send + 'static>> + Send + Sync + 'static, )
Register (or replace) a credential for proactive management.
is_fresh must be side-effect-free (may be called on every
ensure_fresh/sweep tick) — async so a caller whose freshness check
needs a blocking read (e.g. an OS keychain call, which can hang on a
slow/unresponsive Secret Service D-Bus daemon on headless Linux) can
route it through tokio::task::spawn_blocking instead of stalling
the tokio worker thread this scheduler’s own async tasks run on
(reagent P1 on #2260). refresh performs the actual refresh and is
responsible for persisting the result itself (and for NOT persisting
anything on failure) — and for classifying a failure as
RefreshErrorKind::Transient (worth retrying) vs
::PermanentAuthFailure (the credential itself is rejected; only a
fresh login can fix it — see that type’s own doc comment).
Sourcepub fn state(&self, credential_id: &str) -> Option<CredentialState>
pub fn state(&self, credential_id: &str) -> Option<CredentialState>
The credential’s current coordination state, if registered. Read by
muxbus::stale_sign_in to surface NeedsReauth distinctly from a
routine in-progress refresh. Not used by ensure_fresh itself, which
always dispatches through the reducer regardless.
Sourcepub async fn ensure_fresh(&self, credential_id: &str) -> Result<(), String>
pub async fn ensure_fresh(&self, credential_id: &str) -> Result<(), String>
Ensure credential_id is fresh, single-flight-guarded. If another
caller is already mid-refresh for this id, this waits for that
attempt to finish, then re-checks freshness rather than starting a
second refresh. Returns Err if the id was never registered.
Sourcepub async fn run_sweep_loop(self: Arc<Self>, interval: Duration)
pub async fn run_sweep_loop(self: Arc<Self>, interval: Duration)
Background sweep — checks every registered credential every
interval and proactively refreshes anything stale. Skips entries
currently NeedsReauth: retrying a credential already known to
require a fresh human login is pointless and just hammers the
backing server; ensure_fresh called on-demand still re-checks
those (see state’s own doc comment). Spawn once via tokio::spawn;
runs until the process exits.
fn notifier_for(&self, id: &str) -> Arc<Notify> ⓘ
fn wake(&self, id: &str)
Sourcefn trace(&self, events: &[Event])
fn trace(&self, events: &[Event])
Map diagnostics-only reducer events to tracing — auth.broker.*
message prefixes land in muxlog auth’s existing filter regex
(\bauth\.\w+|...) with zero changes needed there. Control-flow
events (RunFreshnessCheck/RunRefresh/AlreadyInFlight/
Unregistered) are acted on directly by callers and not
double-logged here — every ensure_fresh call would otherwise emit
noise even when nothing changed.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for RefreshScheduler
impl !RefUnwindSafe for RefreshScheduler
impl !UnwindSafe for RefreshScheduler
impl Send for RefreshScheduler
impl Sync for RefreshScheduler
impl Unpin for RefreshScheduler
impl UnsafeUnpin for RefreshScheduler
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more