Last active
April 26, 2017 19:30
-
-
Save aprice/8f0b7f82046a0ac10b3b77eb15b7bc0e to your computer and use it in GitHub Desktop.
Simple, un-typed fan-in/fan-out result collator. Easy to customize for type safety.
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
type Collator struct { | |
results chan interface{} | |
errors chan error | |
wg *sync.WaitGroup | |
} | |
func NewCollator() *Collator { | |
return &Collator{ | |
results: make(chan interface{}), | |
errors: make(chan error), | |
wg: new(sync.WaitGroup), | |
} | |
} | |
// Start workers, THEN call Collate() to collect results and errors. | |
func (c *Collator) Collate() ([]interface{}, []error) { | |
wgc := make(chan struct{}) | |
go func() { | |
c.wg.Wait() | |
wgc <- struct{}{} | |
}() | |
errs := make([]error, 0) | |
results := make([]interface{}, 0) | |
done := false | |
for !done { | |
select { | |
case err := <-c.errors: | |
errs = append(errs, err) | |
case result := <-c.results: | |
results = append(results, result) | |
case <-wgc: | |
done = true | |
} | |
} | |
return results, errs | |
} | |
// Call with result immediately before returning from goroutine. | |
func (c *Collator) Success(result interface{}) { | |
c.results <- result | |
c.wg.Done() | |
} | |
// Call with error immediately before returning from goroutine. | |
func (c *Collator) Failure(err error) { | |
c.errors <- err | |
c.wg.Done() | |
} | |
// Call immediately before returning from goroutine when a work item is determined by business logic should be skipped. | |
func (c *Collator) Skip() { | |
c.wg.Done() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment