Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bucket: expose Available() and Capacity() #10

Merged
merged 2 commits into from
Nov 25, 2015
Merged

Conversation

hongchaodeng
Copy link
Contributor

Hi,

The current token bucket implementation is great. Nonetheless we need some underlying data to implement more powerful functionalities.

For example, if we want to implement a function CanAccept which only checks available tokens without taking it; implement a function that exports rate limiter's metrics to better understand current flow and bottleneck on our services. Both functions will benefit if we can get the underlying data like avail and capacity, including the already public Rate().

Let me know if there are questions. Highly appreciate it if anyone can help review this issue. Thanks!

@@ -171,6 +171,16 @@ func (tb *Bucket) takeAvailable(now time.Time, count int64) int64 {
return count
}

// Available returns the number of available tokens
func (tb *Bucket) Available() int64 {
return tb.avail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tb.mu should be held while accessing tb.avail

@axw
Copy link
Contributor

axw commented Nov 24, 2015

Seems fine to me, with one small fix; deferring to @rogpeppe, the author, though.

@@ -171,6 +171,18 @@ func (tb *Bucket) takeAvailable(now time.Time, count int64) int64 {
return count
}

// Available returns the number of available tokens
func (tb *Bucket) Available() int64 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we'd better also doc that It will be negative when there are consumers waiting for tokens.

@rogpeppe
Copy link
Contributor

Thanks for this.
This is good in principle, but could do with a little work to make it correct and tested.

Please rebase to a single commit before re-proposing, thanks.

@hongchaodeng
Copy link
Contributor Author

Thanks @rogpeppe for your reply. I realized my mistake and fixed it.
I have also added a test for the internal available().

I squash all I want to do in single commit. However, I add another commit to update gocheck and math.Abs -- the second one made the test not working.

Let me know if there are questions. Thanks again!

@hongchaodeng
Copy link
Contributor Author

@rogpeppe
Changed naming to TestAvailable()

@hongchaodeng hongchaodeng force-pushed the master branch 2 times, most recently from e65d914 to 99e1293 Compare November 25, 2015 17:18
@hongchaodeng
Copy link
Contributor Author

@rogpeppe
Addressed all comments. PTAL.


expectCountAfterTake int64
expectCountAfterSleep int64
}{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}{{

to save an indent level.

Also, please move the tests to just before TestAvailable.

@rogpeppe
Copy link
Contributor

Thanks very much for making these changes. LGTM modulo some comments above.

sleep: time.Second,
expectCountAfterTake: 1,
expectCountAfterSleep: 2,
}, { // shouldn't fill before interval
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rogpeppe
Add two more tests to check boundaries. PTAL.

@rogpeppe
Copy link
Contributor

LGTM with one trivial suggestion.

expectCountAfterTake int64
expectCountAfterSleep int64
}{{
about: "should fill tokens after interval",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rogpeppe
Added about in table and test failure output.

@@ -171,6 +171,28 @@ func (tb *Bucket) takeAvailable(now time.Time, count int64) int64 {
return count
}

// Available returns the number of available tokens.
// It will be negative when there are consumers waiting for tokens.
// Note that this method is inherently racy - the returned count
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than "inherently racy" (since the available number is actually computed in a thread-safe way), maybe clarify that the returned number of available tokens does not guarantee calls like Take/TakeAvailable will succeed (since the available tokens could have changed in the meantime), and that this is primarily for introspection/metrics/reporting/debugging?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, thanks.
@hongchaodeng How about this?

// Available returns the number of available tokens.
// It will be negative when there are consumers waiting for tokens.
// Note that if this returns greater than zero,
// it does not guarantee that calls that take tokens
// from the buffer will succeed, as the number of available
// tokens could have changed in the meantime.
// This method is intended primarily for metrics reporting
// and debugging.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'll land this now and make that change in another PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

rogpeppe added a commit that referenced this pull request Nov 25, 2015
Bucket: expose Available() and Capacity()
@rogpeppe rogpeppe merged commit 3ebb82b into juju:master Nov 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants