class StatelyDB::Common::Auth::AuthTokenProvider::Actor
def refresh_token_impl
-
(String)
- The new access token
def refresh_token_impl Sync do token_result = @token_fetcher.fetch new_expires_in_secs = token_result.expires_in_secs new_expires_at_unix_secs = Time.now.to_i + new_expires_in_secs # only update the token state if the new expiry is later than the current one if @token_state.nil? || new_expires_at_unix_secs > @token_state.expires_at_unix_secs @token_state = TokenState.new(token: token_result.token, expires_at_unix_secs: new_expires_at_unix_secs) else # otherwise use the existing expiry time for scheduling the refresh new_expires_in_secs = @token_state.expires_at_unix_secs - Time.now.to_i end # Schedule a refresh of the token ahead of the expiry time # Calculate a random multiplier between 0.9 and 0.95 to to apply to the expiry # so that we refresh in the background ahead of expiration, but avoid # multiple processes hammering the service at the same time. jitter = (Random.rand * 0.05) + 0.9 delay_secs = new_expires_in_secs * jitter # do this on the fiber scheduler (the root scheduler) to avoid infinite recursion @scheduled ||= Fiber.scheduler.async do # Kernel.sleep is non-blocking if Ruby 3.1+ and Async 2+ # https://github.com/socketry/async/issues/305#issuecomment-1945188193 sleep(delay_secs) refresh_token @scheduled = nil end @token_state.token end end