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) {