@@ -98,6 +98,15 @@ func (bs *Bitswap) sendBlocks(ctx context.Context, env *engine.Envelope) {
98
98
}
99
99
100
100
func (bs * Bitswap ) provideWorker (px process.Process ) {
101
+ // FIXME: OnClosingContext returns a _custom_ context type.
102
+ // Unfortunately, deriving a new cancelable context from this custom
103
+ // type fires off a goroutine. To work around this, we create a single
104
+ // cancelable context up-front and derive all sub-contexts from that.
105
+ //
106
+ // See: https://github.com/ipfs/go-ipfs/issues/5810
107
+ ctx := procctx .OnClosingContext (px )
108
+ ctx , cancel := context .WithCancel (ctx )
109
+ defer cancel ()
101
110
102
111
limit := make (chan struct {}, provideWorkerMax )
103
112
@@ -108,7 +117,6 @@ func (bs *Bitswap) provideWorker(px process.Process) {
108
117
}()
109
118
ev := logging.LoggableMap {"ID" : wid }
110
119
111
- ctx := procctx .OnClosingContext (px ) // derive ctx from px
112
120
defer log .EventBegin (ctx , "Bitswap.ProvideWorker.Work" , ev , k ).Done ()
113
121
114
122
ctx , cancel := context .WithTimeout (ctx , provideTimeout ) // timeout ctx
@@ -123,7 +131,7 @@ func (bs *Bitswap) provideWorker(px process.Process) {
123
131
// _ratelimited_ number of workers to handle each key.
124
132
for wid := 2 ; ; wid ++ {
125
133
ev := logging.LoggableMap {"ID" : 1 }
126
- log .Event (procctx . OnClosingContext ( px ) , "Bitswap.ProvideWorker.Loop" , ev )
134
+ log .Event (ctx , "Bitswap.ProvideWorker.Loop" , ev )
127
135
128
136
select {
129
137
case <- px .Closing ():
0 commit comments