duanqin9507 2019-01-03 16:53
浏览 57

依赖轮询程序始终运行的Go应用,有关确保其稳定性的建议

So my application relies on a goroutine that polls every x seconds.

func main() {
   // ...
   go p.StartPoller();
}

What are some tips to make sure this poller is always running?

I'm just weary of things maybe because I don't understand fully the concept of error trapping in go. Since errors are values, and assuming I don't or any of the libraries I use call panic(), and no null pointer references or array out of bounds any code inside of this goroutine should not crash the goroutine correct?

func (p *Poller) StartPoller() {
        ticker := time.NewTicker(3 * time.Second)
        defer ticker.Stop() 

        for {
            <-ticker.C
            // code here
        }

    }
  • 写回答

1条回答 默认 最新

  • dpj0015 2019-01-03 17:00
    关注

    You are right, the code you posted should never panic and hence "crash" the goroutine.

    As a best practice, to ensure the // code here also doesn't do that, "wrap" it in a function (anonymous or named one), and use recover() (deferred!) in that. This will ensure that the polling task will also never "crash" the polling scheduler.

    Something like this:

    func (p *Poller) StartPoller() {
        ticker := time.NewTicker(3 * time.Second)
        defer ticker.Stop()
    
        for {
            <-ticker.C
    
            func() {
                defer func() {
                    if r := recover(); r != nil {
                        fmt.Println("Recovered: %v", r)
                    }
                }()
    
                // code here
                // If this would panic, it will be recovered...
            }()
        }
    }
    

    And even if the poller is to be always running, I would still add a "shutdown" channel to it, giving the possibility of graceful termination:

    func (p *Poller) StartPoller(shutdown <-chan struct{}) {
        ticker := time.NewTicker(3 * time.Second)
        defer ticker.Stop()
    
        for {
            select {
            case <-ticker.C:
            case <-shutdown:
                return
            }
    
            func() {
                defer func() {
                    if r := recover(); r != nil {
                        fmt.Println("Recovered: %v", r)
                    }
                }()
    
                // code here
                // If this would panic, it will be recovered...
            }()
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料