我如何将工人返回到 Go 中的工人池

我正在实施一个可以从渠道获取工作的工作人员池。一直超时后,我发现当一个worker fcn内部发生panic时,即使我做了恢复机制,worker还是不会再回到pool中。

在 golang 操场上,我能够重现这个问题:

修改后的游乐场代码:

package main


import "fmt"

import "time"

import "log"


func recovery(id int, results chan<- int) {

    if r := recover(); r != nil {

        log.Print("IN RECOVERY FUNC - Failed worker: ",id)  

        results <- 0

    }

}


func worker(id int, jobs <-chan int, results chan<- int) {

    for j := range jobs {

    defer recovery(id, results)

    if id == 1 {

        panic("TEST")

    }

        fmt.Println("worker", id, "started job", j)

        time.Sleep(time.Second)

        fmt.Println("worker", id, "finished job", j)

        results <- j * 2

    }

}


func main() {

    jobs := make(chan int, 100)

    results := make(chan int, 100)

    for w := 1; w <= 3; w++ {

        go worker(w, jobs, results)

    }

    for j := 1; j <= 10; j++ {

        jobs <- j

    }

    close(jobs)

    for a := 1; a <= 10; a++ {

        <-results

    }

}

为了测试,我在使用 worker 1 时实施了恐慌。运行时,函数会按预期发生恐慌,并按预期进入恢复状态(也不会将值推送到通道中),但是 worker 1 似乎永远不会回来。


没有恐慌的输出:


worker 3 started job 1

worker 1 started job 2

worker 2 started job 3

worker 1 finished job 2

worker 1 started job 4

worker 3 finished job 1

worker 3 started job 5

worker 2 finished job 3

worker 2 started job 6

worker 3 finished job 5

worker 3 started job 7

worker 1 finished job 4

worker 1 started job 8

worker 2 finished job 6

worker 2 started job 9

worker 1 finished job 8

worker 1 started job 10

worker 3 finished job 7

worker 2 finished job 9

worker 1 finished job 10

恐慌输出:


worker 3 started job 1

2009/11/10 23:00:00 RECOVERY Failed worker: 1

worker 2 started job 3

worker 2 finished job 3

worker 2 started job 4

worker 3 finished job 1

worker 3 started job 5

worker 3 finished job 5

worker 3 started job 6

worker 2 finished job 4

worker 2 started job 7

worker 2 finished job 7

worker 2 started job 8

worker 3 finished job 6

worker 3 started job 9

worker 3 finished job 9

worker 3 started job 10

worker 2 finished job 8

worker 3 finished job 10

恢复后(或在恢复过程中)如何将工作人员 1 返回池中


千巷猫影
浏览 122回答 1
1回答

翻翻过去那场雪

如果你关心这些错误,你可以将一个errors通道传递给辅助函数,如果他们遇到一个error,将它发送到通道然后continue。主循环可以处理这些错误。或者,如果您不关心错误,只需continue跳过该作业即可。该continue语句基本上停止处理循环的迭代,并继续下一个。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go