Reputation: 5260
I have two algorithm for same task, one is best for some cases and one for some other cases.
So I would like to start two goroutines at the same time whenever processing the task, and only use the result returned by the first finished goroutine.
Also, in the result, I need to know it is returned by which algorithm. And if I think the first returned result is not right, I would like to wait for the second result.
I read thru the doc of https://golang.org/pkg/sync/, seems it can only wait for all goroutine finish.
How can I implement this idea in golang?
Upvotes: 1
Views: 3084
Reputation: 302
You could use Buffer Channel to achieve that, simple code is:
package main
import (
"fmt"
)
type Result struct {
Value string
Algorithm string
}
func DoTaskA(out chan *Result) {
out <- &Result{"A", "A"}
}
func DoTaskB(out chan *Result) {
out <- &Result{"B", "B"}
}
func IsGood(re *Result) bool {
return re.Value == "B"
}
func main() {
out := make(chan *Result, 1)
go DoTaskA(out)
go DoTaskB(out)
for {
re := <- out
if IsGood(re) {
fmt.Println("The chosen one is:", re.Algorithm)
return
}
}
}
Upvotes: -1
Reputation: 3437
I don't think you need to use sync
, though I'm sure you could come up with a solution that does. I think the simplest solution is to:
Something like this:
type Result struct {
Value string
Algorithm string
}
func (r *Result) String() string {
return r.Value
}
func A(in string, out chan *Result) {
out <- &Result{"A", "A"}
}
func B(in string, out chan *Result) {
out <- &Result{"B", "B"}
}
func main() {
data := []string{"foo", "bar", "baz"}
for _, datum := range data {
resultChan := make(chan *Result, 2)
expectedResult := "B"
go A(datum, resultChan)
go B(datum, resultChan)
result := <-resultChan
if result.Value != expectedResult {
fmt.Println("Unexpected result: ", result)
result = <-resultChan
}
fmt.Println("Got result: ", result)
}
}
Upvotes: 3