install global validation throttle, use reasonable defaults.

This commit is contained in:
vyzo 2018-01-13 21:15:40 +02:00
parent 856a25c8eb
commit edcb251ad1

View File

@ -19,8 +19,9 @@ import (
const ( const (
ID = protocol.ID("/floodsub/1.0.0") ID = protocol.ID("/floodsub/1.0.0")
defaultValidateConcurrency = 10
defaultValidateTimeout = 150 * time.Millisecond defaultValidateTimeout = 150 * time.Millisecond
defaultValidateConcurrency = 100
defaultValidateThrottle = 8192
) )
var log = logging.Logger("floodsub") var log = logging.Logger("floodsub")
@ -61,6 +62,9 @@ type PubSub struct {
// sendMsg handles messages that have been validated // sendMsg handles messages that have been validated
sendMsg chan *sendReq sendMsg chan *sendReq
// validateThrottle limits the number of active validation goroutines
validateThrottle chan struct{}
peers map[peer.ID]chan *RPC peers map[peer.ID]chan *RPC
seenMessages *timecache.TimeCache seenMessages *timecache.TimeCache
@ -101,6 +105,7 @@ func NewFloodSub(ctx context.Context, h host.Host, opts ...Option) (*PubSub, err
addSub: make(chan *addSubReq), addSub: make(chan *addSubReq),
getTopics: make(chan *topicReq), getTopics: make(chan *topicReq),
sendMsg: make(chan *sendReq), sendMsg: make(chan *sendReq),
validateThrottle: make(chan struct{}, defaultValidateThrottle),
myTopics: make(map[string]map[*Subscription]struct{}), myTopics: make(map[string]map[*Subscription]struct{}),
topics: make(map[string]map[peer.ID]struct{}), topics: make(map[string]map[peer.ID]struct{}),
peers: make(map[peer.ID]chan *RPC), peers: make(map[peer.ID]chan *RPC),
@ -123,6 +128,13 @@ func NewFloodSub(ctx context.Context, h host.Host, opts ...Option) (*PubSub, err
return ps, nil return ps, nil
} }
func WithValidateThrottle(n int) Option {
return func(ps *PubSub) error {
ps.validateThrottle = make(chan struct{}, n)
return nil
}
}
// processLoop handles all inputs arriving on the channels // processLoop handles all inputs arriving on the channels
func (p *PubSub) processLoop(ctx context.Context) { func (p *PubSub) processLoop(ctx context.Context) {
defer func() { defer func() {
@ -361,9 +373,16 @@ func (p *PubSub) pushMsg(subs []*Subscription, src peer.ID, msg *Message) {
} }
if needval { if needval {
// validation is asynchronous // validation is asynchronous and globally throttled with the throttleValidate semaphore
// XXX vyzo: do we want a global validation throttle here? select {
go p.validate(subs, src, msg) case p.validateThrottle <- struct{}{}:
go func() {
p.validate(subs, src, msg)
<-p.validateThrottle
}()
default:
log.Warningf("message validation throttled; dropping message from %s", src)
}
return return
} }