Blog

也谈「优雅中断定时任务」

Cover Image for 也谈「优雅中断定时任务」
ZD
ZD

忘了搜什么东西,看到了某社区的这篇优雅中断定时任务的文章,试着提出一种的解决方法。

问题

下面的定时器用法示例,无法关闭定时器

t := time.NewTicker(3 * time.Second)
timeout := time.After(10 * time.Second)
go func() {
        for {   
                <-t.C
                // ...
        }       
}()
<-timeout
// ...

解决

用一个 exitChan 的 channel 对象,结合 select 语法,同时等待定时器和退出 channel 的信号,实现了 gorotine 的优雅退出。

package main

import (
	"fmt"
	"time"
)

func main() {
	exitChan := make(chan bool)
	t := time.NewTicker(3 * time.Second)
	timeout := time.After(10 * time.Second)
	go func() {
	    for {   
			select {
				case <-t.C:
					fmt.Println("tick ...")
				case <-exitChan:
					goto exit
			}
	    }
	exit:
	}()
	<-timeout
	close(exitChan)
	fmt.Println("Hello, 世界")
}

输出:

tick ...
tick ...
tick ...
Hello, 世界

最近大半年以来,断断续续的学习 nsq 的源码,对其简单清晰的风格留下深刻印象,同时也习得了不少实用的小技巧。此用法正是来源于 NSQ, 在 NSQ 项目中应用十分广泛。