【发布时间】:2018-09-17 07:30:15
【问题描述】:
当接收到没有特定顺序的“退出”信号时,除了调用其他函数之外,我还需要按需停止 HTTP 服务器。
在我尝试实现observer pattern 之类的东西时,我发现“方便”创建一个频道(quit := make(chan struct{}),比如说“主题”,然后在每个 goroutines 上“ observers”在该频道上收听 <-quit 等到更改后再继续。
我一次触发所有功能的方法是关闭频道close(quit) 而不是写入它,我已经尝试过这个并且到目前为止工作,但想知道这种方法是否有一些缺点或者是否有更好的/实现类似行为/模式的惯用方式。
package main
import (
"log"
"net/http"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
srv := &http.Server{Addr: ":8080"}
wg.Add(1)
go func() {
log.Println(srv.ListenAndServe())
wg.Done()
}()
quit := make(chan struct{})
go func() {
<-quit
if err := srv.Close(); err != nil {
log.Printf("HTTP server Shutdown: %v", err)
}
}()
wg.Add(1)
go func() {
<-quit
log.Println("just waiting 1")
wg.Done()
}()
wg.Add(1)
go func() {
<-quit
log.Println("just waiting 2")
wg.Done()
}()
<-time.After(2 * time.Second)
close(quit)
wg.Wait()
}
【问题讨论】:
-
关闭频道以向任意数量的各方广播单个事件是很常见的事情。 (恕我直言,在这里使用 struct{} 过于聪明了。)
-
这是一种合理的方法,也正是context.Context 的工作原理。
标签: go observer-pattern