caching
fun TokenProvider.Companion.caching(safetyMargin: Duration = 60.seconds, now: () -> Long = { System.currentTimeMillis() }, fetch: suspend () -> Token): TokenProvider
Wrap a token source in caching, early refresh, and refresh coalescing.
Deliberately independent of where the token comes from: caching is a property of holding a token, not of how one was obtained, so the same decorator serves a backend doing a client-credentials exchange and a mobile client calling its own server.
Parameters
safetyMargin
refresh this long before expiry, so a token cannot lapse mid-request and surface to the caller as a spurious 401.
now
millisecond clock, injectable so tests need no real waiting.
fetch
mints a fresh token. Called at most once per refresh, however many callers are waiting.