Skip to content

Instantly share code, notes, and snippets.

@odeke-em
Created December 28, 2016 20:16
Show Gist options
  • Save odeke-em/8a9d2f8dfa06e364f6f5d7ae583eea15 to your computer and use it in GitHub Desktop.
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
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