I have a worker pool small program and I want to be able to stop/end the execution of a single job and return a result for the job, if a "cancel" request has been received for that job.
Currently I have this, but if I send a "cancel" message and attempt to return on the "results" channel, nothing happens and my job continues until it is finished. How can I achieve the functionality I am looking for (stoping a job without closing the channel)?
var opChan = make(chan OperationReq, numJobs)
var opResChan = make(chan string, numJobs)
func main() {
operations := []string{
"1", "2", "3", "4", "5", "6", "7", "8",
}
fmt.Println("Starting workers")
for i := 0; i < 2; i++ {
go worker(opChan, opResChan)
}
for _, o := range operations {
cancelChan := make(chan bool)
opChan <- OperationReq{
OperationID: o,
CancelChan: cancelChan,
}
time.Sleep(1 * time.Second)
fmt.Println("will send cancel req")
cancelChan <- true
}
for a := 1; a <= len(operations); a++ {
res := <-opResChan
fmt.Println(res)
}
}
type OperationReq struct {
OperationID string
CancelChan chan bool
}
func checkCancelled(o *OperationReq) bool {
select {
case cancel := <-o.CancelChan:
fmt.Println("received cancel request: ", cancel, " for operation: ", o.OperationID)
return true
default:
return false
}
}
func worker(op <-chan OperationReq, results chan<- string) {
for o := range op {
fmt.Println("Starting operation: ", o.OperationID)
if checkCancelled(&o) {
results <- "Canceled operation: " + o.OperationID
return
}
time.Sleep(time.Second * time.Duration(10)) //time.Duration(rand.Intn(15)))
if checkCancelled(&o) {
results <- "Canceled operation: " + o.OperationID
return
}
fmt.Println("Finished operation: ", o.OperationID)
results <- "Done operation: " + o.OperationID
}
}