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

时间:2019-01-03 16:53:10

标签: go scheduler goroutine ticker stability

因此,我的应用程序依赖于每x秒轮询一次的goroutine。

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

确保此轮询程序始终运行的一些提示是什么?

我只是对事情感到厌倦,也许是因为我不完全了解go中错误陷阱的概念。由于错误是值,并且假设我没有使用任何库或我使用了panic()函数,并且没有空指针引用或数组超出范围此goroutine中的任何代码都不会使goroutine正确崩溃

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

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

    }

1 个答案:

答案 0 :(得分:2)

您是对的,您发布的代码永远不会崩溃,因此会“破坏” goroutine。

作为最佳实践,要确保// code here也不执行此操作,请将其“包装”到一个函数(匿名或命名的函数)中,并在其中使用recover()(推迟!)。 。这样可以确保轮询任务也永远不会“崩溃”轮询调度程序。

类似这样的东西:

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...
        }()
    }
}

即使轮询程序将始终运行,我仍然会向其添加一个“关闭”通道,以实现正常终止的可能性:

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...
        }()
    }
}