【发布时间】:2017-10-09 00:51:33
【问题描述】:
我有一个程序,它定期检查外部邮箱是否有消息,并有一个用户视图,允许他们查看消息并终止程序。
剥离到最小的功能看起来像这样
package main
import (
"log"
"time"
)
func main() {
log.Println("Hello, playground")
quit := make(chan bool)
data := make(chan string)
go func() {
for {
select {
case <-quit:
log.Println("Quitting")
close(data)
return
case data <- fetch():
// Wait until e.g. exactly 0,10,20,30,40 or 50 mins past the hour
interval := time.Second * 5
now := time.Now()
time.Sleep(now.Truncate(interval).Add(interval).Sub(now))
}
}
}()
go func() {
time.Sleep(12 * time.Second) // actually user presses a "quit" button
quit <- true
}()
loop:
for {
select {
case info, ok := <-data:
if !ok {
break loop
}
log.Println("Fetched", info)
}
}
log.Println("Goodbye, playground")
}
func fetch() string {
log.Println("Fetching")
return "message"
}
你可以run this in the Go Playground
输出是
2009/11/10 23:00:00 Hello, playground
2009/11/10 23:00:00 Fetching
2009/11/10 23:00:00 Fetched message
2009/11/10 23:00:05 Fetching
2009/11/10 23:00:05 Fetched message
2009/11/10 23:00:10 Fetching
2009/11/10 23:00:10 Fetched message
2009/11/10 23:00:15 Fetching
2009/11/10 23:00:15 Quitting
2009/11/10 23:00:15 Goodbye, playground
注意
-
"23:00:15 Fetching"是我没想到的。 - 程序在 23:00:15 退出,而不是在 23:00:12,因为它正在休眠。
后者在我的程序中会成为一个问题,因为它在检查消息之间使用了 10 分钟的睡眠时间。将退出延迟那么长时间会使程序看起来非常迟钝。
从this answer了解到,你可以使用time.After()创建一个可以中断的循环延迟。
我应该如何最好地将它应用到我的程序中?
【问题讨论】:
标签: go concurrency sleep scheduler channel