-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Description
I have the same issue as #17601, but the issue was closed and locked with this reason:
This doesn't seem to rise to the level of new API. You don't have to "copy the section of code underneath the first <-t.C", you just have to put the code in its own function and call that function once at the start and once after each timeout interval. That seems clear enough.
However, "call the function once at the start" does not work when you are not in control of when the function is called.
Consider this clumsy implementation of a rate limiting in rateLimited, vs. the much more concise and elegant one in rateLimitedImmediate:
package main
import (
"fmt"
"sync"
"time"
)
var interval = time.Second
type rateLimited struct {
rateLimiter <-chan time.Time
f func() string
}
func (r *rateLimited) do() string {
<-r.rateLimiter
return r.f()
}
type rateLimitedImmediate struct {
mu sync.Mutex
rateLimiter <-chan time.Time
f func() string
}
func (r *rateLimitedImmediate) do() string {
r.mu.Lock()
defer r.mu.Unlock()
defer func() { r.rateLimiter = time.After(interval) }()
<-r.rateLimiter
return r.f()
}
func main() {
r := &rateLimited{
rateLimiter: time.Tick(interval),
f: func() string { return "result" },
}
fmt.Println(r.do())
fmt.Println(r.do())
fmt.Println(r.do())
r2 := &rateLimitedImmediate{
rateLimiter: time.After(0), // start immediately
f: func() string { return "result" },
}
fmt.Println(r2.do())
fmt.Println(r2.do())
fmt.Println(r2.do())
}Just that the nice implementation in rateLimited cannot start immediately.
I am not in control of calling the function myself, the library client does that.
So I second the need for a stdlib solution like proposed in the original issue, and hope the issue can be re-opened (or discussed here).