ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Credential.Refresh.Internal

Description

The implementation behind Ecluse.Core.Credential.Refresh, which documents the policy and re-exports the curated surface. Importing this module opts out of that stability promise, the convention text and bytestring use, so production code imports the public one.

Synopsis

Configuration

data RefreshConfig Source #

Refresh policy with injected mint, clock, jitter and observers.

Constructors

RefreshConfig 

Fields

defaultRefreshConfig :: RefreshConfig Source #

Default policy knobs. Unwired rcMint and rcClock throw Unconfigured.

The refreshing provider

refreshingProvider :: RefreshConfig -> IO CredentialProvider Source #

Build a cached provider, minting eagerly so an initial mint failure aborts construction.

refreshingProviderWith :: IO () -> RefreshConfig -> IO CredentialProvider Source #

Add a test hook between the single-flight claim and the mint runner.

Telemetry reporters

data RefreshReporter Source #

Observe refresh outcomes with the active token's absolute expiry, absent for non-expiring tokens.

Constructors

RefreshReporter 

Fields

noRefreshReporter :: RefreshReporter Source #

The inert refresh reporter: records nothing on either outcome.

data CredentialReporters Source #

The telemetry observers a refreshing provider records through, bundled into one value.

Constructors

CredentialReporters 

Fields

noCredentialReporters :: CredentialReporters Source #

The inert pair: a provider built with it records nothing on either signal.

Failure

data CredentialError Source #

A failure from credential minting or refresh policy.

Constructors

BreakerOpen

The token expired with the mint breaker open, so no mint was attempted.

Unconfigured Text

An effectful leaf still holds its defaultRefreshConfig placeholder.

MintedTokenAlreadyExpired

An already-expired mint is treated as a mint failure.

State and pure/transition helpers (exposed for direct testing)

data CacheState Source #

The mutable state of a refreshing provider.

Constructors

CacheState 

Fields

data ServeAction Source #

What a serve/decide decision resolves to.

Constructors

ServeCached AuthToken

The cached token is valid and no refresh is due: serve it.

ServeAndRefresh AuthToken

Valid but past the refresh threshold: serve it, refresh in background.

MintNow

Expired: the caller must mint synchronously (the slow path).

decide :: TVar CacheState -> UTCTime -> STM ServeAction Source #

Claim a mint atomically when one is due, or block until an in-flight refresh frees the flag. The caller must release a claim with releaseSingleFlight.

refreshDueAt :: RefreshConfig -> UTCTime -> AuthToken -> IO (Maybe UTCTime) Source #

When a freshly minted token's refresh should fire. Jitter only pulls the rcRefreshAt fraction of the token's lifetime earlier, never later.

onMintSuccess :: AuthToken -> Maybe UTCTime -> CacheState -> CacheState Source #

Fold a successful mint into the cache. guardInFlight releases the single-flight flag around the mint, not this fold, so the flag clears even on an async exception.

onMintFailure :: RefreshConfig -> UTCTime -> CacheState -> CacheState Source #

Fold a failed mint into the cache. The cached token stays in place and the breaker advances under the configured threshold and cooldown.

releaseSingleFlight :: TVar CacheState -> IO () Source #

Release the single-flight flag. serve runs it under guardInFlight inside the masked scope that claimed it, so the flag clears on every exit, an async cancel included.