// RateLimited returns a rate limited Notifier. only limit goroutines // will be spawned. If limit is zero, no rate limiting happens. This // is the same as `Notifier{}`. func RateLimited(limit int) Notifier { n := Notifier{} if limit > 0 { n.lim = ratelimit.NewRateLimiter(process.Background(), limit) } return n }
func (bs *Bitswap) provideWorker(px process.Process) { limiter := ratelimit.NewRateLimiter(px, provideWorkerMax) limitedGoProvide := func(k key.Key, wid int) { ev := logging.LoggableMap{"ID": wid} limiter.LimitedGo(func(px process.Process) { ctx := procctx.OnClosingContext(px) // derive ctx from px defer log.EventBegin(ctx, "Bitswap.ProvideWorker.Work", ev, &k).Done() ctx, cancel := context.WithTimeout(ctx, provideTimeout) // timeout ctx defer cancel() if err := bs.network.Provide(ctx, k); err != nil { log.Error(err) } }) } // worker spawner, reads from bs.provideKeys until it closes, spawning a // _ratelimited_ number of workers to handle each key. limiter.Go(func(px process.Process) { for wid := 2; ; wid++ { ev := logging.LoggableMap{"ID": 1} log.Event(procctx.OnClosingContext(px), "Bitswap.ProvideWorker.Loop", ev) select { case <-px.Closing(): return case k, ok := <-bs.provideKeys: if !ok { log.Debug("provideKeys channel closed") return } limitedGoProvide(k, wid) } } }) }