Skip to content

Instantly share code, notes, and snippets.

@moonsub-kim
Created March 3, 2022 13:48
Show Gist options
  • Save moonsub-kim/09fbf39f3dd53b6fc102012985901acc to your computer and use it in GitHub Desktop.
Save moonsub-kim/09fbf39f3dd53b6fc102012985901acc to your computer and use it in GitHub Desktop.
refresh provider
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