Reputation: 10856
I'm trying to run several tasks concurrently and get the result or error back.
//data channels
ch := make(chan int)
ch2 := make(chan int)
ch2 := make(chan int)
//error channels
errCh := make(chan error)
errCh2 := make(chan error)
errCh3 := make(chan error)
//functions
go taskF(ch, errCh)
go taskF2(ch2, errCh2)
go taskF3(ch3, errCh3)
Then I start checking on each error. If there is any error we print it otherwise we print the result of each task
err := <-errCh
if err != nil{
print('we have an error ')
return
}
err2 := <-errCh2
if err2 != nil{
print('we have an error 2')
return
}
err3 := <-errCh3
if err3!= nil{
print('we have an error 3')
return
}
Then if there is no error I collect the values returned though each channel
task := <-ch
task2 := <-ch2
task3 := <-ch3
print("task %v task2 %v task3 %v", task, task2, task3)
I'm wondering if I'm doing it right. I'm worried that the code quite verbose. I was thinking to use buffered channels for errors but i can't figure it out how to check all the errors. I think it would also be nice to somehow sync the errors within the goroutines so that if there is an error on one goroutine the other goroutines would stop but I don't know any way to do in an unblocking manner.
Upvotes: 4
Views: 5437
Reputation: 1559
Consider using only one channel for synchronization, and having this channel include an error state (see the Result struct). Whenever you receive a Result, make sure the error state is nil. Wrapping each task in a Task struct will allow you to call Stop on each task when one returns an error. Depending on your exact application there may be better ways to handle this, such as WaitGroups (http://golang.org/pkg/sync/#WaitGroup).
type Result struct {
Val int
Err error
}
type Task struct {
stopped bool
}
func (t *Task) Stop() {
t.stopped = true
}
func (t *Task) Run(doneChan chan Result) {
// long-running task here
// periodically check t.stopped
doneChan <- Result{Val: ..., Err: nil}
}
Upvotes: 1