Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

simplify TimeLimiter, fixing its tests #1088

Merged
merged 5 commits into from
Oct 23, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix tests, cleanup
Dieterbe committed Oct 10, 2018
commit 25f85221db832d35b3181cb20f412cac1690c7e9
23 changes: 6 additions & 17 deletions idx/memory/time_limit.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package memory

import (
"fmt"
"time"

"github.com/davecgh/go-spew/spew"
)
import "time"

// TimeLimiter limits the rate of a set of serial operations.
// It does this by tracking how much time has been spent (updated via Add()),
@@ -32,7 +27,6 @@ func NewTimeLimiter(window, limit time.Duration, now time.Time) *TimeLimiter {
window: window,
limit: limit,
}
spew.Dump(l)
return &l
}

@@ -47,8 +41,6 @@ func (l *TimeLimiter) add(now time.Time, d time.Duration) {
l.timeSpent = d
l.since = now.Add(-d)
l.next = l.since.Add(l.window)
fmt.Println("added and updated")
spew.Dump(l)
return
}
l.timeSpent += d
@@ -77,25 +69,22 @@ func (l *TimeLimiter) wait(now time.Time) time.Duration {
l.timeSpent = 0
l.since = now
l.next = now.Add(l.window)
fmt.Println("wait and update")
spew.Dump(l)
return 0
}
if l.timeSpent < l.limit {
return 0
}

// now <= next
// now >= since
// here we know that:
// since <= now <= next
// timespent >= limit
excess := l.timeSpent - l.limit
multiplier := l.window / l.limit
timeToPass := excess * multiplier
timeToPass := l.timeSpent * multiplier
timePassed := now.Sub(l.since)

// not sure if this should happen, but let's be safe anyway
if timePassed >= timeToPass {
if timePassed > timeToPass {
return 0
}
fmt.Println("wait and now is", now)
return timeToPass - timePassed
}
10 changes: 4 additions & 6 deletions idx/memory/time_limit_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package memory

import (
"fmt"
"testing"
"time"
)
@@ -11,17 +10,16 @@ var now = time.Unix(10, 0)
func shouldTake(t *testing.T, tl *TimeLimiter, workDone, expDur time.Duration, info string) {

// account for work done, as well as moving our clock forward by the same amount
now.Add(workDone)
now = now.Add(workDone)
tl.add(now, workDone)

fmt.Println("now is now", now)
dur := tl.wait(now)
if dur != expDur {
t.Fatalf("scenario %s. expected wait %s, got wait %s", info, expDur, dur)
}

// fake the "sleep" so we're a properly behaving caller
now.Add(dur)
now = now.Add(dur)
}

func TestTimeLimiter(t *testing.T) {
@@ -36,10 +34,10 @@ func TestTimeLimiter(t *testing.T) {
shouldTake(t, tl, 10*time.Millisecond, 0, "window 1: work done: 15ms")
shouldTake(t, tl, 80*time.Millisecond, 0, "window 1: work done: 95ms")
shouldTake(t, tl, 4*time.Millisecond, 0, "window 1: work done: 99ms")
shouldTake(t, tl, 3*time.Millisecond, time.Second-102*time.Millisecond, "window 1: work done: 102ms")
shouldTake(t, tl, 3*time.Millisecond, (1020-102)*time.Millisecond, "window 1: work done: 102ms")

// TEST 2 : Now that we waited until a full window, should be able to up to limit work again
shouldTake(t, tl, 50*time.Millisecond, 0, "window 2: work done: 50ms")
shouldTake(t, tl, 40*time.Millisecond, 0, "window 2: work done: 90ms")
shouldTake(t, tl, 40*time.Millisecond, time.Second-130*time.Millisecond, "window 2: work done: 130ms")
shouldTake(t, tl, 40*time.Millisecond, (1300-130)*time.Millisecond, "window 2: work done: 130ms")
}