I need to cancel any previous goroutine
on every function call. How would that be handled in Go? I've seen channels used but I can't quite wrap my head around the examples and whether a select statement is necessary.
The desired result would be that only the last request subtasks are ran.
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 5; i++ {
go handleRequest(i)
time.Sleep(1 * time.Second) // Time between requests
}
}
func handleRequest(incr int) {
fmt.Println("New request registered: ", incr + 1)
for i := 0; i <= 3; i++ {
fmt.Println("Request: ", incr + 1, " | Sub-task: ", i + 1)
time.Sleep(2 * time.Second) // Time processing
}
return
}
Goroutine cancellation can be done using a context. If you need to cancel a previous goroutine, start it with a context and cancel it when a new one starts. You have to write the goroutine to periodically check for the context:
var ctx context.Context
var cancel context.CancelFunc
for i := 0; i < 5; i++ {
if cancel!=nil {
// cancel previous goroutine
cancel()
}
ctx,cancel=context.WithCancel(context.Background())
// start goroutine with a new context
go handleRequest(ctx,i)
time.Sleep(1 * time.Second) // Time between requests
}
if cancel!=nil {
cancel()
}
In your goroutine, you have to check for cancellation:
func handleRequest(ctx context.Context,incr int) {
fmt.Println("New request registered: ", incr + 1)
for i := 0; i <= 3; i++ {
fmt.Println("Request: ", incr + 1, " | Sub-task: ", i + 1)
time.Sleep(2 * time.Second) // Time processing
select {
case <-ctx.Done():
// canceled
return
default:
// not canceled
}
}
return
}