Created
March 3, 2022 13:48
-
-
Save moonsub-kim/09fbf39f3dd53b6fc102012985901acc to your computer and use it in GitHub Desktop.
refresh provider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"sync" | |
"time" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/aws/credentials" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/s3" | |
) | |
func main() { | |
sess := session.New() | |
// call credRefreshTicker.Stop() to stop the cred refresh | |
// useful when the custom credential provider will not | |
// be used for the lifetime of the app. | |
credRefreshTicker := time.NewTicker(1 * time.Hour) | |
s3Svc := s3.New(sess, &aws.Config{ | |
Credentials: credentials.NewCredentials(&RefreshProvider{ | |
Provider: customProvider, | |
Ticker: credRefreshTicker, | |
}), | |
}) | |
for { | |
s3Svc.GetObject(&s3.GetObjectInput{ | |
Bucket: aws.String("bucket"), | |
Key: aws.String("key"), | |
}) | |
<-time.Tick(5 * time.Hour) | |
} | |
} | |
type RefreshProvider struct { | |
// Nested Provider to call Retrieve and IsExpired on | |
credentials.Provider | |
// How often the credential provider should be refreshed. | |
Ticker *time.Ticker | |
creds credentials.Value | |
err error | |
mux sync.RWMutex | |
initRunner sync.Once | |
} | |
func (p *RefreshProvider) Retrieve() (credentials.Value, error) { | |
p.initRunner.Do(func() { | |
p.creds, p.err = p.Provider.Retrieve() | |
go p.periodicRefresh() | |
}) | |
p.mux.RLock() | |
defer p.mux.RUnlock() | |
return p.creds, p.err | |
} | |
func (p *RefreshProvider) periodicRefresh() { | |
for { | |
_, ok := <-p.Ticker.C | |
if !ok { | |
break | |
} | |
p.mux.Lock() | |
// Probably want to log the returned error | |
creds, err := p.Provider.Retrieve() | |
if err != nil { | |
if p.Provider.IsExpired() { | |
// If the credentials have expired, and still unable | |
// to retrieve new credentials set the error | |
p.err = err | |
} | |
p.mux.Unlock() | |
log.Println("ERROR: failed to refresh credentials provider,", err) | |
continue | |
} | |
p.err = nil | |
p.creds = creds | |
p.mux.Unlock() | |
} | |
} | |
func (p *RefreshProvider) IsExpired() bool { | |
p.mux.RLock() | |
defer p.mux.RUnlock() | |
return p.Provider.IsExpired() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment