2018-11-07 21:16:13 +00:00
|
|
|
package multiplex
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync/atomic"
|
|
|
|
|
2019-08-17 10:23:26 +00:00
|
|
|
"github.com/juju/ratelimit"
|
2018-11-07 21:16:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Valve needs to be universal, across all sessions that belong to a user
|
2019-08-07 14:43:42 +00:00
|
|
|
type LimitedValve struct {
|
2018-11-07 21:16:13 +00:00
|
|
|
// traffic directions from the server's perspective are refered
|
|
|
|
// exclusively as rx and tx.
|
|
|
|
// rx is from client to server, tx is from server to client
|
|
|
|
// DO NOT use terms up or down as this is used in usermanager
|
|
|
|
// for bandwidth limiting
|
2019-08-17 10:23:26 +00:00
|
|
|
rxtb *ratelimit.Bucket
|
|
|
|
txtb *ratelimit.Bucket
|
2018-11-07 21:16:13 +00:00
|
|
|
|
2019-07-22 12:42:39 +00:00
|
|
|
rx *int64
|
|
|
|
tx *int64
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
|
|
|
|
2019-08-07 14:43:42 +00:00
|
|
|
type UnlimitedValve struct{}
|
|
|
|
|
|
|
|
func MakeValve(rxRate, txRate int64) *LimitedValve {
|
2019-07-25 11:17:29 +00:00
|
|
|
var rx, tx int64
|
2019-08-07 14:43:42 +00:00
|
|
|
v := &LimitedValve{
|
2019-08-17 10:23:26 +00:00
|
|
|
rxtb: ratelimit.NewBucketWithRate(float64(rxRate), rxRate),
|
|
|
|
txtb: ratelimit.NewBucketWithRate(float64(txRate), txRate),
|
2019-08-04 16:16:18 +00:00
|
|
|
rx: &rx,
|
|
|
|
tx: &tx,
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
2019-08-07 14:43:42 +00:00
|
|
|
var UNLIMITED_VALVE = &UnlimitedValve{}
|
2019-07-25 11:17:29 +00:00
|
|
|
|
2019-08-07 14:43:42 +00:00
|
|
|
func (v *LimitedValve) rxWait(n int) { v.rxtb.Wait(int64(n)) }
|
|
|
|
func (v *LimitedValve) txWait(n int) { v.txtb.Wait(int64(n)) }
|
|
|
|
func (v *LimitedValve) AddRx(n int64) { atomic.AddInt64(v.rx, n) }
|
|
|
|
func (v *LimitedValve) AddTx(n int64) { atomic.AddInt64(v.tx, n) }
|
|
|
|
func (v *LimitedValve) GetRx() int64 { return atomic.LoadInt64(v.rx) }
|
|
|
|
func (v *LimitedValve) GetTx() int64 { return atomic.LoadInt64(v.tx) }
|
|
|
|
func (v *LimitedValve) Nullify() (int64, int64) {
|
2019-07-22 12:42:39 +00:00
|
|
|
rx := atomic.SwapInt64(v.rx, 0)
|
|
|
|
tx := atomic.SwapInt64(v.tx, 0)
|
|
|
|
return rx, tx
|
|
|
|
}
|
2019-08-07 14:43:42 +00:00
|
|
|
|
|
|
|
func (v *UnlimitedValve) rxWait(n int) {}
|
|
|
|
func (v *UnlimitedValve) txWait(n int) {}
|
|
|
|
func (v *UnlimitedValve) AddRx(n int64) {}
|
|
|
|
func (v *UnlimitedValve) AddTx(n int64) {}
|
|
|
|
func (v *UnlimitedValve) GetRx() int64 { return 0 }
|
|
|
|
func (v *UnlimitedValve) GetTx() int64 { return 0 }
|
|
|
|
func (v *UnlimitedValve) Nullify() (int64, int64) { return 0, 0 }
|
|
|
|
|
|
|
|
type Valve interface {
|
|
|
|
rxWait(n int)
|
|
|
|
txWait(n int)
|
|
|
|
AddRx(n int64)
|
|
|
|
AddTx(n int64)
|
|
|
|
GetRx() int64
|
|
|
|
GetTx() int64
|
|
|
|
Nullify() (int64, int64)
|
|
|
|
}
|