11package query
22
33import (
4+ "context"
45 "fmt"
56 "time"
6-
7- goprocess "github.com/jbenet/goprocess"
87)
98
109/*
@@ -149,14 +148,16 @@ type Results interface {
149148 Next () <- chan Result // returns a channel to wait for the next result
150149 NextSync () (Result , bool ) // blocks and waits to return the next result, second parameter returns false when results are exhausted
151150 Rest () ([]Entry , error ) // waits till processing finishes, returns all entries at once.
152- Close () error // client may call Close to signal early exit
151+ Close () // client may call Close to signal early exit
153152}
154153
155154// results implements Results
156155type results struct {
157156 query Query
158- proc goprocess.Process
159157 res <- chan Result
158+
159+ ctx context.Context
160+ cancel context.CancelFunc
160161}
161162
162163func (r * results ) Next () <- chan Result {
@@ -176,12 +177,12 @@ func (r *results) Rest() ([]Entry, error) {
176177 }
177178 es = append (es , e .Entry )
178179 }
179- <- r .proc . Closed () // wait till the processing finishes.
180+ <- r .ctx . Done () // wait till the processing finishes.
180181 return es , nil
181182}
182183
183- func (r * results ) Close () error {
184- return r . proc . Close ()
184+ func (r * results ) Close () {
185+ r . cancel ()
185186}
186187
187188func (r * results ) Query () Query {
@@ -199,17 +200,21 @@ func (r *results) Query() Query {
199200// - datastores must respect <-Process.Closing(), which intermediates
200201// an early close signal from the client.
201202type ResultBuilder struct {
202- Query Query
203- process goprocess.Process
204- Output chan Result
203+ Query Query
204+ Output chan Result
205+
206+ ctx context.Context
207+ cancel context.CancelFunc
205208}
206209
207210// Results returns a Results to to this builder.
208211func (rb * ResultBuilder ) Results () Results {
209212 return & results {
210213 query : rb .Query ,
211- proc : rb .process ,
212214 res : rb .Output ,
215+
216+ ctx : rb .ctx ,
217+ cancel : rb .cancel ,
213218 }
214219}
215220
@@ -225,9 +230,9 @@ func NewResultBuilder(q Query) *ResultBuilder {
225230 Query : q ,
226231 Output : make (chan Result , bufSize ),
227232 }
228- b .process = goprocess .WithTeardown (func () error {
233+ b .ctx , b .cancel = context .WithCancel (context .Background ())
234+ context .AfterFunc (b .ctx , func () {
229235 close (b .Output )
230- return nil
231236 })
232237 return b
233238}
@@ -238,10 +243,11 @@ func NewResultBuilder(q Query) *ResultBuilder {
238243// DEPRECATED: This iterator is impossible to cancel correctly. Canceling it
239244// will leave anything trying to write to the result channel hanging.
240245func ResultsWithChan (q Query , res <- chan Result ) Results {
241- proc := func (worker goprocess.Process , out chan <- Result ) {
246+ proc := func (ctx context.Context , cancel context.CancelFunc , out chan <- Result ) {
247+ defer cancel ()
242248 for {
243249 select {
244- case <- worker . Closing (): // client told us to close early
250+ case <- ctx . Done (): // client told us to close early
245251 return
246252 case e , more := <- res :
247253 if ! more {
@@ -250,7 +256,7 @@ func ResultsWithChan(q Query, res <-chan Result) Results {
250256
251257 select {
252258 case out <- e :
253- case <- worker . Closing (): // client told us to close early
259+ case <- ctx . Done (): // client told us to close early
254260 return
255261 }
256262 }
@@ -260,11 +266,8 @@ func ResultsWithChan(q Query, res <-chan Result) Results {
260266 b := NewResultBuilder (q )
261267
262268 // go consume all the entries and add them to the results.
263- b .process .Go (func (worker goprocess.Process ) {
264- proc (worker , b .Output )
265- })
269+ go proc (b .ctx , b .cancel , b .Output )
266270
267- go b .process .CloseAfterChildren () //nolint
268271 return b .Results ()
269272}
270273
@@ -287,12 +290,12 @@ func ResultsReplaceQuery(r Results, q Query) Results {
287290 switch r := r .(type ) {
288291 case * results :
289292 // note: not using field names to make sure all fields are copied
290- return & results {q , r .proc , r .res }
293+ return & results {q , r .res , r .ctx , r . cancel }
291294 case * resultsIter :
292295 // note: not using field names to make sure all fields are copied
293296 lr := r .legacyResults
294297 if lr != nil {
295- lr = & results {q , lr .proc , lr .res }
298+ lr = & results {q , lr .res , lr .ctx , lr . cancel }
296299 }
297300 return & resultsIter {q , r .next , r .close , lr }
298301 default :
@@ -316,19 +319,17 @@ func ResultsFromIterator(q Query, iter Iterator) Results {
316319 }
317320}
318321
319- func noopClose () error {
320- return nil
321- }
322+ func noopClose () {}
322323
323324type Iterator struct {
324325 Next func () (Result , bool )
325- Close func () error // note: might be called more than once
326+ Close func () // note: might be called more than once
326327}
327328
328329type resultsIter struct {
329330 query Query
330331 next func () (Result , bool )
331- close func () error
332+ close func ()
332333 legacyResults * results
333334}
334335
@@ -340,13 +341,12 @@ func (r *resultsIter) Next() <-chan Result {
340341func (r * resultsIter ) NextSync () (Result , bool ) {
341342 if r .legacyResults != nil {
342343 return r .legacyResults .NextSync ()
343- } else {
344- res , ok := r .next ()
345- if ! ok {
346- r .close ()
347- }
348- return res , ok
349344 }
345+ res , ok := r .next ()
346+ if ! ok {
347+ r .close ()
348+ }
349+ return res , ok
350350}
351351
352352func (r * resultsIter ) Rest () ([]Entry , error ) {
@@ -364,11 +364,11 @@ func (r *resultsIter) Rest() ([]Entry, error) {
364364 return es , nil
365365}
366366
367- func (r * resultsIter ) Close () error {
367+ func (r * resultsIter ) Close () {
368368 if r .legacyResults != nil {
369- return r .legacyResults .Close ()
369+ r .legacyResults .Close ()
370370 } else {
371- return r .close ()
371+ r .close ()
372372 }
373373}
374374
@@ -384,22 +384,21 @@ func (r *resultsIter) useLegacyResults() {
384384 b := NewResultBuilder (r .query )
385385
386386 // go consume all the entries and add them to the results.
387- b .process .Go (func (worker goprocess.Process ) {
387+ go func (ctx context.Context , cancel context.CancelFunc , out chan <- Result ) {
388+ defer cancel ()
388389 defer r .close ()
389390 for {
390391 e , ok := r .next ()
391392 if ! ok {
392- break
393+ return
393394 }
394395 select {
395- case b . Output <- e :
396- case <- worker . Closing (): // client told us to close early
396+ case out <- e :
397+ case <- ctx . Done (): // client told us to close early
397398 return
398399 }
399400 }
400- })
401-
402- go b .process .CloseAfterChildren () //nolint
401+ }(b .ctx , b .cancel , b .Output )
403402
404403 r .legacyResults = b .Results ().(* results )
405404}
0 commit comments