The for loop waits for the stop channel to emit a struct{}. The stop channel is unbuffered, so <-stop waits until someone writes into stop. This blocks the for loop after the first call to go Writer().
Use select instead of if to read from stop:
for {
Loop:
go Writer()
select {
case <-stop:
break Loop
default:
}
}
Be aware, however, that the infinite for loop produces Writer goroutines nonstop. At least on a single-core CPU, neither the Writers nor the main routine would not have a chance to run at all.
Here is a stripped-down and modified version of your code. It adds Sleep() to Worker() and replaces the if by a select:
package main
import (
"fmt"
"time"
)
var (
stop = make(chan struct{})
done = make(chan struct{})
)
func main() {
go Worker()
time.Sleep(20 * time.Second)
fmt.Println("Stop")
stop <- struct{}{}
<-done
}
func Worker() {
Loop:
for {
go Writer()
time.Sleep(time.Second)
select {
case <-stop:
fmt.Println("Stop received")
break Loop
default:
}
}
done <- struct{}{}
}
func Writer() {
time.Sleep(10 * time.Second)
fmt.Println("Writer")
}