@cryptotaxi247 / kubo / commits / 22f0b8796

fix panic in bitswap working limit spawning

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Oct 18, 2015 at 12:25 UTC 22f0b8796120182a8ebd71ecb948de8294cd551d
1 file changed +26 -22
exchange/bitswap/workers.go
+26 -22
@@ -5,7 +5,6 @@ import (
5
6 process "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
7 procctx "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/context"
8 - ratelimit "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/ratelimit"
8 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
10 key "github.com/ipfs/go-ipfs/blocks/key"
@@ -74,43 +73,48 @@ func (bs *Bitswap) taskWorker(ctx context.Context, id int) {
73
74 func (bs *Bitswap) provideWorker(px process.Process) {
75
77 - limiter := ratelimit.NewRateLimiter(px, provideWorkerMax)
76 + limit := make(chan struct{}, provideWorkerMax)
77
78 limitedGoProvide := func(k key.Key, wid int) {
79 + defer func() {
80 + // replace token when done
81 + <-limit
82 + }()
83 ev := logging.LoggableMap{"ID": wid}
81 - limiter.LimitedGo(func(px process.Process) {
84
83 - ctx := procctx.OnClosingContext(px) // derive ctx from px
84 - defer log.EventBegin(ctx, "Bitswap.ProvideWorker.Work", ev, &k).Done()
85 + ctx := procctx.OnClosingContext(px) // derive ctx from px
86 + defer log.EventBegin(ctx, "Bitswap.ProvideWorker.Work", ev, &k).Done()
87
86 - ctx, cancel := context.WithTimeout(ctx, provideTimeout) // timeout ctx
87 - defer cancel()
88 + ctx, cancel := context.WithTimeout(ctx, provideTimeout) // timeout ctx
89 + defer cancel()
90
89 - if err := bs.network.Provide(ctx, k); err != nil {
90 - log.Error(err)
91 - }
92 - })
91 + if err := bs.network.Provide(ctx, k); err != nil {
92 + log.Error(err)
93 + }
94 }
95
96 // worker spawner, reads from bs.provideKeys until it closes, spawning a
97 // _ratelimited_ number of workers to handle each key.
97 - limiter.Go(func(px process.Process) {
98 - for wid := 2; ; wid++ {
99 - ev := logging.LoggableMap{"ID": 1}
100 - log.Event(procctx.OnClosingContext(px), "Bitswap.ProvideWorker.Loop", ev)
98 + for wid := 2; ; wid++ {
99 + ev := logging.LoggableMap{"ID": 1}
100 + log.Event(procctx.OnClosingContext(px), "Bitswap.ProvideWorker.Loop", ev)
101
102 + select {
103 + case <-px.Closing():
104 + return
105 + case k, ok := <-bs.provideKeys:
106 + if !ok {
107 + log.Debug("provideKeys channel closed")
108 + return
109 + }
110 select {
111 case <-px.Closing():
112 return
105 - case k, ok := <-bs.provideKeys:
106 - if !ok {
107 - log.Debug("provideKeys channel closed")
108 - return
109 - }
110 - limitedGoProvide(k, wid)
113 + case limit <- struct{}{}:
114 + go limitedGoProvide(k, wid)
115 }
116 }
113 - })
117 + }
118 }
119
120 func (bs *Bitswap) provideCollector(ctx context.Context) {