Created
December 28, 2016 20:16
-
-
Save odeke-em/8a9d2f8dfa06e364f6f5d7ae583eea15 to your computer and use it in GitHub Desktop.
Demo how to cancel asynchronous processing after getting exactly n successful results
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"time" | |
"github.com/odeke-em/semalim" | |
) | |
type echo struct { | |
id uint64 | |
} | |
func (e echo) Do() (interface{}, error) { return fmt.Sprintf("done %d", e.id), nil } | |
func (e echo) Id() interface{} { return e.id } | |
var _ semalim.Job = (*echo)(nil) | |
func main() { | |
jobsChan := make(chan semalim.Job) | |
cancellation := make(chan bool) | |
go func() { | |
defer close(jobsChan) | |
throttle := time.NewTicker(1e9 / 20) | |
id := uint64(0) | |
working := true | |
for working { | |
select { | |
case <-cancellation: // If they cancel on us, stop all work and break | |
working = false | |
break | |
case <-throttle.C: | |
jobsChan <- &echo{id: id} | |
id += 1 | |
} | |
} | |
}() | |
defer close(cancellation) | |
resultsChan := semalim.Run(jobsChan, 10) | |
success := uint64(0) | |
for res := range resultsChan { | |
if success >= 10000 { | |
// We've reached out limit, time to break out | |
// but also send the cancellation signal | |
fmt.Printf("\033[32mcancellation now\033[00m\n") | |
cancellation <- true | |
break | |
} | |
// We are only counting successes | |
if err := res.Err(); err == nil { | |
success += 1 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment