mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
Two packages were named for the same word and meant different things. network/ dialed peers, exchanged keys, throttled and tracked them; nets/ tracked which chains share a validator set and when they have all bootstrapped. One letter apart, and neither name said which was which. The peer layer is mesh — the word this estate already uses for it, in lux-rs/node's own mesh.rs. That frees network for the thing that is actually a network: a set of chains sharing a validator set. A network holds chains; a chain belongs to one network. github.com/luxfi/p2p stays what it is, the gossip library the VMs use. Three concerns, three names, none of them borrowed from another. Co-authored-by: Hanzo Dev <[email protected]>
63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package throttling
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
|
|
"golang.org/x/time/rate"
|
|
)
|
|
|
|
var _ net.Listener = (*throttledListener)(nil)
|
|
|
|
// Wraps [listener] and returns a net.Listener that will accept at most
|
|
// [maxConnsPerSec] connections per second.
|
|
// [maxConnsPerSec] must be non-negative.
|
|
func NewThrottledListener(listener net.Listener, maxConnsPerSec float64) net.Listener {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
return &throttledListener{
|
|
ctx: ctx,
|
|
ctxCancelFunc: cancel,
|
|
listener: listener,
|
|
limiter: rate.NewLimiter(rate.Limit(maxConnsPerSec), int(maxConnsPerSec)+1),
|
|
}
|
|
}
|
|
|
|
// [throttledListener] is a net.Listener that rate-limits
|
|
// acceptance of incoming connections.
|
|
// Note that InboundConnUpgradeThrottler rate-limits _upgrading_ of
|
|
// inbound connections, whereas throttledListener rate-limits
|
|
// _acceptance_ of inbound connections.
|
|
type throttledListener struct {
|
|
// [ctx] is cancelled when Close() is called
|
|
ctx context.Context
|
|
// [ctxCancelFunc] cancels [ctx] when it's called
|
|
ctxCancelFunc func()
|
|
// The underlying listener
|
|
listener net.Listener
|
|
// Handles rate-limiting
|
|
limiter *rate.Limiter
|
|
}
|
|
|
|
func (l *throttledListener) Accept() (net.Conn, error) {
|
|
// Wait until the rate-limiter says to accept the
|
|
// next incoming connection. If l.Close() is called,
|
|
// Wait will return immediately.
|
|
if err := l.limiter.Wait(l.ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
return l.listener.Accept()
|
|
}
|
|
|
|
func (l *throttledListener) Close() error {
|
|
// Cancel [l.ctx] so Accept() will return immediately
|
|
l.ctxCancelFunc()
|
|
return l.listener.Close()
|
|
}
|
|
|
|
func (l *throttledListener) Addr() net.Addr {
|
|
return l.listener.Addr()
|
|
}
|