-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfaucet.go
58 lines (49 loc) · 1.93 KB
/
faucet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
Copyright 2018 Joseph Cumines
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package faucet implements a simple pattern for polling based rate limiting, using Golang's time.Ticker.
// Note that any nil arguments to any method or function in this package will trigger a panic.
package faucet
import (
"context"
"sync"
"time"
)
type (
// Pipe controls the rate of transfer between 1..n inputs, and 0..n outputs, where input is, for each tick,
// polled from _any_ of the inputs (the order checked is adjusted each tick in a round-robin fashion), and all
// outputs will receive the input, and must all return before the next tick is started.
// Basically, this implementation is geared towards fan-in to fan-out, allowing it to be used in a wide range
// of situations.
// Note that unlike time.Ticker it will start the first tick immediately on start.
Pipe struct {
mutex sync.Mutex
open sync.Once
close sync.Once
err error
done chan struct{}
stop chan struct{}
ticker *time.Ticker
inputs []func(context.Context) (interface{}, bool, error)
outputs []func(context.Context, interface{}) error
ctx context.Context
cancel context.CancelFunc
}
)
// RatePerMinute converts a rate per minute to a duration to achieve it, note it will return 0 for count 0, and
// negative duration for negative count.
func RatePerMinute(count int) time.Duration {
if count == 0 {
return 0
}
return time.Minute / time.Duration(count)
}