Reputation: 1920
I need to create a html page which has two buttons, one will start a goroutine, which has an infinite loop, and other button need to break the infinite loop. As from my readings I understood that a goroutine can't be killed from outside it. Is there anyway to implement this? My code is as follows:
command := c.GetString("command") // from client to determine which button is clicked
quit := make(chan bool)
switch command {
case "start": // Button to start goroutine
go func() {
i := 0
for {
select {
case <- quit:
return
default:
fmt.Println("i: ", i)
i++
time.Sleep(3000 * time.Millisecond)
}
}
}()
case "stop": // Button to stop goroutine
quit <- true
}
Upvotes: 1
Views: 461
Reputation: 9136
You are already right about the design. An issue is that you are creating new channels each time you recieve a command. Which means there is no way to communicate with the previously started goroutine. You need to have a quit
channel that stays in scope for between requests. Try something like below (untested):
func listenForCommand() {
var quit chan bool
for {
// command receiver, should fire for each command received
command := c.GetString("command")
switch command {
case "start":
if quit != nil {
continue
}
quit = make(chan bool)
go func() {
i := 0
for {
select {
case <-quit:
return
default:
fmt.Println("i: ", i)
i++
time.Sleep(3000 * time.Millisecond)
}
}
}()
case "stop":
if quit == nil {
continue
}
quit <- true
close(quit)
quit = nil
}
}
}
You can now call listenForCommand()
to start listening for commands. This example presumes that there is another process populating c
so c.GetString("command")
returns a command if available, or blocks and waits for a command to arrive.
Upvotes: 1