Skip to content

Commit ffaf271

Browse files
committed
Use RankedSet for data bucket
1 parent 07ec515 commit ffaf271

File tree

1 file changed

+28
-52
lines changed

1 file changed

+28
-52
lines changed

pkg/auth/oauth/registry/timeoutvalidator.go

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"time"
66

77
"github.com/golang/glog"
8-
"github.com/google/btree"
98

109
apierrors "k8s.io/apimachinery/pkg/api/errors"
1110
"k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -16,30 +15,27 @@ import (
1615
oauthclient "github.com/openshift/origin/pkg/oauth/generated/internalclientset/typed/oauth/internalversion"
1716
oauthclientlister "github.com/openshift/origin/pkg/oauth/generated/listers/oauth/internalversion"
1817
"github.com/openshift/origin/pkg/user/apis/user"
18+
"github.com/openshift/origin/pkg/util/rankedset"
1919
)
2020

2121
var errTimedout = errors.New("token timed out")
2222

23+
// Implements rankedset.Item
2324
type tokenData struct {
2425
token *oauth.OAuthAccessToken
2526
seen time.Time
2627
}
2728

28-
func (a *tokenData) timeout() time.Time {
29+
func (a tokenData) timeout() time.Time {
2930
return a.token.CreationTimestamp.Time.Add(time.Duration(a.token.TimeoutsIn) * time.Second)
3031
}
3132

32-
type tokenDataRef struct {
33-
name string
34-
timeout time.Time
33+
func (a tokenData) Key() string {
34+
return a.token.Name
3535
}
3636

37-
func (a *tokenDataRef) Less(than btree.Item) bool {
38-
39-
if a.timeout.Equal(than.(*tokenDataRef).timeout) {
40-
return a.name < than.(*tokenDataRef).name
41-
}
42-
return a.timeout.Before(than.(*tokenDataRef).timeout)
37+
func (a tokenData) Rank() int64 {
38+
return a.timeout().Unix()
4339
}
4440

4541
func timeoutAsDuration(timeout int32) time.Duration {
@@ -50,8 +46,7 @@ type TimeoutValidator struct {
5046
oauthClients oauthclientlister.OAuthClientLister
5147
tokens oauthclient.OAuthAccessTokenInterface
5248
tokenChannel chan tokenData
53-
data map[string]tokenData
54-
tree *btree.BTree
49+
data *rankedset.RankedSet
5550
minValidTimeout int32
5651
maxFlushTimeout int32
5752
defaultTimeout time.Duration
@@ -61,12 +56,10 @@ type TimeoutValidator struct {
6156

6257
func NewTimeoutValidator(tokens oauthclient.OAuthAccessTokenInterface, oauthClients oauthclientlister.OAuthClientLister, defaultTimeout int32, minValidTimeout int32, maxFlushTimeout int32) *TimeoutValidator {
6358
a := &TimeoutValidator{
64-
oauthClients: oauthClients,
65-
tokens: tokens,
66-
tokenChannel: make(chan tokenData),
67-
data: make(map[string]tokenData),
68-
// FIXME: what is the right degree for the btree
69-
tree: btree.New(32),
59+
oauthClients: oauthClients,
60+
tokens: tokens,
61+
tokenChannel: make(chan tokenData),
62+
data: rankedset.New(),
7063
minValidTimeout: minValidTimeout,
7164
maxFlushTimeout: maxFlushTimeout,
7265
}
@@ -163,21 +156,6 @@ func (a *TimeoutValidator) updateTimeouts() {
163156
}
164157
}
165158

166-
func (a *TimeoutValidator) insert(td tokenData) {
167-
// if there is a token we have to remove it first
168-
oldtd, exists := a.data[td.token.Name]
169-
if exists {
170-
a.delete(oldtd, &tokenDataRef{oldtd.token.Name, oldtd.timeout()})
171-
}
172-
a.data[td.token.Name] = td
173-
a.tree.ReplaceOrInsert(&tokenDataRef{td.token.Name, td.timeout()})
174-
}
175-
176-
func (a *TimeoutValidator) delete(td tokenData, tdr *tokenDataRef) {
177-
a.tree.Delete(tdr)
178-
delete(a.data, td.token.Name)
179-
}
180-
181159
func (a *TimeoutValidator) update(td tokenData) error {
182160
// Obtain the timeout interval for this client
183161
delta := a.clientTimeout(td.token.ClientName)
@@ -207,37 +185,34 @@ func (a *TimeoutValidator) update(td tokenData) error {
207185
}
208186

209187
func (a *TimeoutValidator) flush(flushHorizon time.Time) {
210-
flushedTokens := 0
211-
totalTokens := len(a.data)
212-
var retrylist []tokenData
213-
214188
glog.V(5).Infof("Flushing tokens timing out before %s", flushHorizon)
215189

216-
for item := a.tree.Min(); item != nil; item = a.tree.Min() {
217-
tdr := item.(*tokenDataRef)
218-
if tdr.timeout.After(flushHorizon) {
219-
// out of items within the flush Horizon
220-
break
221-
}
222-
td := a.data[tdr.name]
190+
// grab all tokens that need to be update in this flush interval
191+
// and remove them from the stored data, they either flush now or never
192+
tokenList := a.data.LessThan(flushHorizon.Unix(), true)
193+
194+
var retryList []tokenData
195+
flushedTokens := 0
196+
197+
for _, item := range tokenList {
198+
td := item.(tokenData)
223199
err := a.update(td)
224200
switch {
225201
case err == nil:
226202
flushedTokens++
227203
case apierrors.IsConflict(err) || apierrors.IsServerTimeout(err):
228204
glog.V(5).Infof("Token update deferred for token=%q, retriable error: %v",
229205
td.token.Name, err)
230-
retrylist = append(retrylist, td)
206+
retryList = append(retryList, td)
231207
default:
232208
glog.V(5).Infof("Token timeout for user=%q client=%q scopes=%v was not updated: %v",
233209
td.token.UserName, td.token.ClientName, td.token.Scopes, err)
234210
}
235-
// In all cases we remove the token from the data set
236-
a.delete(td, tdr)
237211
}
238212

239-
// we try once more and if it still fails we stop trying here and defer to a future regular update
240-
for _, td := range retrylist {
213+
// we try once more and if it still fails we stop trying here and defer
214+
// to a future regular update if the token is used again
215+
for _, td := range retryList {
241216
err := a.update(td)
242217
if err != nil {
243218
glog.V(5).Infof("Token timeout for user=%q client=%q scopes=%v was not updated: %v",
@@ -247,7 +222,8 @@ func (a *TimeoutValidator) flush(flushHorizon time.Time) {
247222
}
248223
}
249224

250-
glog.V(5).Infof("Flushed %d tokens out of %d in bucket", flushedTokens, totalTokens)
225+
glog.V(5).Infof("Successfully flushed %d tokens out of %d",
226+
flushedTokens, len(tokenList))
251227
}
252228

253229
func (a *TimeoutValidator) Run(stopCh <-chan struct{}) {
@@ -284,7 +260,7 @@ func (a *TimeoutValidator) Run(stopCh <-chan struct{}) {
284260
// if channel closes terminate
285261
return
286262
case td := <-a.tokenChannel:
287-
a.insert(td)
263+
a.data.Insert(td)
288264
// if this token is going to time out before the timer, fire
289265
// immediately (safety margin is added to avoid racing too close)
290266
tokenTimeout := td.timeout()

0 commit comments

Comments
 (0)