You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: token_cache.go
    path of file: ./repos/sliver/vendor/github.com/aws/smithy-go/auth/bearer
    
    the code of the file until where you have to start completion: package bearer

import (
	"context"
	"fmt"
	"sync/atomic"
	"time"

	smithycontext "github.com/aws/smithy-go/context"
	"github.com/aws/smithy-go/internal/sync/singleflight"
)

// package variable that can be override in unit tests.
var timeNow = time.Now

// TokenCacheOptions provides a set of optional configuration options for the
// TokenCache TokenProvider.
type TokenCacheOptions struct {
	// The duration before the token will expire when the credentials will be
	// refreshed. If DisableAsyncRefresh is true, the RetrieveBearerToken calls
	// will be blocking.
	//
	// Asynchronous refreshes are deduplicated, and only one will be in-flight
	// at a time. If the token expires while an asynchronous refresh is in
	// flight, the next call t
    
func (p *TokenCache) tryAsyncRefresh(ctx context.Context) {
	if p.options.AsyncRefreshMinimumDelay != 0 {
		var lastRefreshAttempt time.Time
		if v := p.lastRefreshAttemptTime.Load(); v != nil {
			lastRefreshAttempt = v.(time.Time)
		}

		if timeNow().Before(lastRefreshAttempt.Add(p.options.AsyncRefreshMinimumDelay)) {
			return
		}
	}

	// Ignore the returned channel so this won't be blocking, and limit the
	// number of additional goroutines created.
	p.sfGroup.DoChan("async-refresh", func() (interface{}, error) {
		res, err := p.refreshBearerToken(ctx)
		if p.options.AsyncRefreshMinimumDelay != 0 {
			var refreshAttempt time.Time
			if err != nil {
				refreshAttempt = timeNow()
			}
			p.lastRefreshAttemptTime.Store(refreshAttempt)
		}

		return res, err
	})
}