Skip to content

Commit

Permalink
fix(cache): retry period (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
vknabel authored Aug 14, 2024
1 parent 670277b commit 8e337cf
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 7 deletions.
39 changes: 32 additions & 7 deletions issuercache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type MultiIssuerCache struct {
cache map[string]*Issuer
cacheLock sync.RWMutex
reloadInterval time.Duration
retryInterval time.Duration
log *slog.Logger
}

Expand All @@ -41,34 +42,50 @@ func NewMultiIssuerCache(log *slog.Logger, ilp IssuerListProvider, ugp UserGette
userGetterProvider: ugp,
cache: make(map[string]*Issuer),
reloadInterval: 30 * time.Minute,
retryInterval: 30 * time.Second,
log: log,
}

for _, opt := range opts {
opt(issuerCache)
}

var (
// flush cache periodically
done = make(chan bool)
isRetrying bool
reloadTicker *time.Ticker
)
// initial update
err := issuerCache.updateCache()
if err != nil {
issuerCache.log.Error("error updating issuer cache", "error", err)
isRetrying = true
reloadTicker = time.NewTicker(issuerCache.retryInterval)
} else {
isRetrying = false
reloadTicker = time.NewTicker(issuerCache.reloadInterval)
}

// flush cache periodically
done := make(chan bool)
ticker := time.NewTicker(issuerCache.reloadInterval)

go func() {
for {
select {
case <-done:
ticker.Stop()
reloadTicker.Stop()
return
case <-ticker.C:

case <-reloadTicker.C:
issuerCache.log.Info("updating issuer cache")
err := issuerCache.updateCache()
if err != nil {
issuerCache.log.Error("error updating issuer cache", "error", err)
issuerCache.log.Error("error updating issuer cache, retrying...", "error", err)
isRetrying = true
reloadTicker.Reset(issuerCache.retryInterval)
continue
}
if isRetrying {
isRetrying = false
reloadTicker.Reset(issuerCache.reloadInterval)
}
}
}
Expand All @@ -88,6 +105,14 @@ func IssuerReloadInterval(duration time.Duration) MultiIssuerUserGetterOption {
}
}

// IssuerRetryInterval lets the client set the issuer cache retry sleep period
func IssuerRetryInterval(duration time.Duration) MultiIssuerUserGetterOption {
return func(o *MultiIssuerCache) *MultiIssuerCache {
o.retryInterval = duration
return o
}
}

func (i *MultiIssuerCache) User(rq *http.Request) (*User, error) {

claims, err := ParseTokenClaimsUnvalidated(rq)
Expand Down
59 changes: 59 additions & 0 deletions issuercache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,65 @@ func TestMultiIssuerCache_reload(t *testing.T) {
assert.Len(t, ic.cache, 1)
}

func TestMultiIssuerCache_retryFailing(t *testing.T) {
ugp := func(ic *IssuerConfig) (UserGetter, error) {
return nil, nil
}

calls := 0

ilp := func() ([]*IssuerConfig, error) {
calls++
return nil, errors.New("expected error")
}
ic, err := NewMultiIssuerCache(slog.New(slog.NewJSONHandler(os.Stdout, nil)), ilp, ugp, IssuerReloadInterval(5*time.Second), IssuerRetryInterval(500*time.Millisecond))
require.NoError(t, err)
assert.Equal(t, 1, calls)
assert.Empty(t, ic.cache)

// wait for reload
time.Sleep(2 * time.Second)

assert.Equal(t, 4, calls)
assert.Empty(t, ic.cache)
}

func TestMultiIssuerCache_retrySecondReload(t *testing.T) {
ugp := func(ic *IssuerConfig) (UserGetter, error) {
return nil, nil
}

calls := 0
issuerList := []*IssuerConfig{}

ilp := func() ([]*IssuerConfig, error) {
calls++
if calls > 1 {
return issuerList, nil
}
return nil, errors.New("expected error")
}
ic, err := NewMultiIssuerCache(slog.New(slog.NewJSONHandler(os.Stdout, nil)), ilp, ugp, IssuerReloadInterval(1*time.Second), IssuerRetryInterval(500*time.Millisecond))
require.NoError(t, err)
assert.Equal(t, 1, calls)
assert.Empty(t, ic.cache)

// prepare list
issuerList = []*IssuerConfig{
{
Annotations: nil,
Tenant: "t1",
Issuer: "http://issuer/t1",
ClientID: "cli-t1",
},
}
// wait for reload
time.Sleep(2 * time.Second)

assert.Equal(t, 3, calls)
assert.Len(t, ic.cache, 1)
}

func TestMultiIssuerCache_syncCache(t *testing.T) {
type fields struct {
ilp IssuerListProvider
Expand Down

0 comments on commit 8e337cf

Please sign in to comment.