优先处理 Select 个具有频道的案例
Priority on Select cases with channel
我有这个功能让里面的方法,运行就一个ticker。我的问题是第二种情况 sigC 仅在 ticker.C 完成 后才有效 ,这并不理想,因为程序运行s 带有标志,所以如果我想更改标志并改变程序的行为,我必须等待 ticker 方法完成 运行ning,这可能需要一些时间。
我的objective是当我按Ctrl+C的时候,程序马上就结束了运行ning
func report() error {
ticker := time.NewTicker(timeConfig)
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt)
for range ticker.C {
select {
case <-ticker.C:
connection = connectionInit()
tagValues, err := fetchLatestTags()
if err != nil {
return err
}
if len(tagValues) >= threshold {
metrics, err := fetchMetrics(tagValues)
if err != nil {
return err
}
if stdout {
err = locally(metrics)
if err != nil {
return err
}
} else {
err = sendMail(metrics)
if err != nil {
return err
}
}
}
connection.Close()
case <-sigC:
return nil
}
}
return nil
}
我尝试了这些彼此非常相似但无济于事的解决方案:
[1]
[2]Priority in Go select statement workaround
如果我理解正确的话,您想做的是用无限循环替换 range-over-channel 循环。即 for range ticker.C { ... }
-> for { ... }
.
并且如果您希望程序而不是 report
函数立即完成而不等待 case <-ticker.C:
块中的代码完成,您应该在分离 goroutine 并将 case <-sigC:
块从 return nil
更新为 os.Exit(1)
.
func report() {
ticker := time.NewTicker(timeConfig)
defer ticker.Stop()
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt)
for {
select {
case <-ticker.C:
go func() {
connection = connectionInit()
tagValues, err := fetchLatestTags()
if err != nil {
return
}
if len(tagValues) >= threshold {
metrics, err := fetchMetrics(tagValues)
if err != nil {
return
}
if stdout {
err = locally(metrics)
if err != nil {
return
}
} else {
err = sendMail(metrics)
if err != nil {
return
}
}
}
connection.Close()
}()
case <-sigC:
os.Exit(1)
}
}
}
我有这个功能让里面的方法,运行就一个ticker。我的问题是第二种情况 sigC 仅在 ticker.C 完成 后才有效 ,这并不理想,因为程序运行s 带有标志,所以如果我想更改标志并改变程序的行为,我必须等待 ticker 方法完成 运行ning,这可能需要一些时间。
我的objective是当我按Ctrl+C的时候,程序马上就结束了运行ning
func report() error {
ticker := time.NewTicker(timeConfig)
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt)
for range ticker.C {
select {
case <-ticker.C:
connection = connectionInit()
tagValues, err := fetchLatestTags()
if err != nil {
return err
}
if len(tagValues) >= threshold {
metrics, err := fetchMetrics(tagValues)
if err != nil {
return err
}
if stdout {
err = locally(metrics)
if err != nil {
return err
}
} else {
err = sendMail(metrics)
if err != nil {
return err
}
}
}
connection.Close()
case <-sigC:
return nil
}
}
return nil
}
我尝试了这些彼此非常相似但无济于事的解决方案:
[1]
[2]Priority in Go select statement workaround
如果我理解正确的话,您想做的是用无限循环替换 range-over-channel 循环。即 for range ticker.C { ... }
-> for { ... }
.
并且如果您希望程序而不是 report
函数立即完成而不等待 case <-ticker.C:
块中的代码完成,您应该在分离 goroutine 并将 case <-sigC:
块从 return nil
更新为 os.Exit(1)
.
func report() {
ticker := time.NewTicker(timeConfig)
defer ticker.Stop()
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt)
for {
select {
case <-ticker.C:
go func() {
connection = connectionInit()
tagValues, err := fetchLatestTags()
if err != nil {
return
}
if len(tagValues) >= threshold {
metrics, err := fetchMetrics(tagValues)
if err != nil {
return
}
if stdout {
err = locally(metrics)
if err != nil {
return
}
} else {
err = sendMail(metrics)
if err != nil {
return
}
}
}
connection.Close()
}()
case <-sigC:
os.Exit(1)
}
}
}