diff --git a/main.go b/main.go index 4f28feba..084ca02d 100644 --- a/main.go +++ b/main.go @@ -56,6 +56,7 @@ type DiscoveryOptions struct { type AdvancedOptions struct { RequestsInFlight int `long:"reqs-in-flight" description:"Parallell in flight requests per file" default:"4" value-name:"REQS"` FilesInFlight int `long:"files-in-flight" description:"Parallell in flight file pulls" default:"8" value-name:"FILES"` + LimitRate int `long:"send-rate" description:"Rate limit for outgoing data" default:"0" value-name:"KBPS"` ScanInterval time.Duration `long:"scan-intv" description:"Repository scan interval" default:"60s" value-name:"INTV"` ConnInterval time.Duration `long:"conn-intv" description:"Node reconnect interval" default:"60s" value-name:"INTV"` } @@ -158,6 +159,9 @@ func main() { for _, t := range opts.Debug.TraceModel { m.Trace(t) } + if opts.Advanced.LimitRate > 0 { + m.LimitRate(opts.Advanced.LimitRate) + } // GUI if !opts.NoGUI && opts.GUIAddr != "" { diff --git a/model/model.go b/model/model.go index 24fca3d4..050bf19b 100644 --- a/model/model.go +++ b/model/model.go @@ -53,6 +53,8 @@ type Model struct { fileLastChanged map[string]time.Time fileWasSuppressed map[string]int + + limitRequestRate chan struct{} } type Connection interface { @@ -97,6 +99,21 @@ func NewModel(dir string) *Model { return m } +func (m *Model) LimitRate(kbps int) { + m.limitRequestRate = make(chan struct{}, kbps) + n := kbps/10 + 1 + go func() { + for { + time.Sleep(100 * time.Millisecond) + for i := 0; i < n; i++ { + select { + case m.limitRequestRate <- struct{}{}: + } + } + } + }() +} + // Trace enables trace logging of the given facility. This is a debugging function; grep for m.trace. func (m *Model) Trace(t string) { m.Lock() @@ -334,6 +351,12 @@ func (m *Model) Request(nodeID, name string, offset uint64, size uint32, hash [] return nil, err } + if m.limitRequestRate != nil { + for s := 0; s < len(buf); s += 1024 { + <-m.limitRequestRate + } + } + return buf, nil }