I've been playing around with this and came up with:
type Function struct{
Function func(*TaskGroup, []interface{})
Args []interface{}
}
type TaskGroup struct{
Group sync.WaitGroup
Functions []Function
}
func (x *TaskGroup) Start() {
for _, Function := range x.Functions{
x.Group.Add(1)
go Function.Function(x, Function.Args)
}
x.Group.Wait()
}
In order to work easier with mutliple functions I have to wait for.
The following tests will work and I do not understand why:
func auxC(x *TaskGroup, args []interface{}){
defer x.Group.Done()
messageOut := args[0].(chan string)
messageOut <- "TestC"
}
func auxD(x *TaskGroup, args []interface{}){
defer x.Group.Done()
messageOut := args[0].(chan string)
messageOut <- "TestD"
}
func TestTaskGroupBaseB(t *testing.T) {
messageC := make(chan string, 1)
messageD := make(chan string, 1)
tg := TaskGroup{
Functions: []Function{
{auxC, []interface{}{messageC}},
{auxD, []interface{}{messageD}},
},
}
tg.Start()
fmt.Println(<- messageC)
fmt.Println(<- messageD)
time.Sleep(100 * time.Millisecond)
}
I first tried with unbuffered channels like this:
messageC := make(chan string)
messageD := make(chan string)
But it doesn't work it just gets stuck forever without doing anything, so i have a few questions:
Refactored code, see comments:
Main/Tests:
func auxC(args []interface{}){
messageOut := args[0].(chan string)
messageOut <- "TestC"
}
func auxD(args []interface{}){
messageOut := args[0].(chan string)
messageOut <- "TestD"
}
func TestTaskGroupBaseB(t *testing.T) {
messageC := make(chan string,1)
messageD := make(chan string,1)
tg := TaskGroup{
Functions: []Function{
{auxC, []interface{}{messageC}},
{auxD, []interface{}{messageD}},
},
}
tg.Wait()
fmt.Println(<- messageC)
fmt.Println(<- messageD)
time.Sleep(100 * time.Millisecond)
}
Task Group:
type Function struct{
Function func([]interface{})
Args []interface{}
}
type TaskGroup struct{
Group sync.WaitGroup
Functions []Function
}
func (x *TaskGroup) Wait() {
for _, function := range x.Functions{
x.Group.Add(1)
go func(x *TaskGroup, f Function){
defer x.Group.Done()
f.Function(f.Args)
}(x, function)
}
x.Group.Wait()
}
Using a channel with buffer size 1, first write buffers data, then goroutines end and you can read the buffered data in the main goroutine.
When channel size is zero a write to the channel blocks until another goroutine reads from it. So both of your goroutines are waiting to write the channels. If you move the Wait() call after the channel reads in main it should work.