我一直在处理试图让我的第一个“goroutine”运行的示例,当我让它运行时,它不会按照 go 文档中的 timer.Reset() 函数的规定工作。
就我而言,我相信我这样做的方式很好,因为我实际上并不关心 chan 缓冲区中的内容,如果有的话。case <-tmr.C:
所有这一切都是为了在发生任何事情时触发case _, ok := <-watcher.Events:
,然后一切都会安静至少一秒钟。这样做的原因是case _, ok := <-watcher.Events:
可以从一到几十个事件相隔微秒,我只关心它们都完成并且事情再次安定下来。
但是,我担心按照文档中说的“必须做”的方式去做是行不通的。如果我知道 go 更好,我会说文档有缺陷,因为它假设缓冲区中有一些东西可能没有,但我不知道 go 足够好来有信心做出这个决定,所以我希望一些专家出来那里可以启发我。
下面是代码。我没有把它放在操场上,因为我必须做一些清理工作(删除对程序其他部分的调用),而且我不确定如何让它对文件系统更改做出反应以显示它工作。
我已经在代码中清楚地标记了哪些替代方法有效,哪些无效。
func (pm *PluginManager) LoadAndWatchPlugins() error {
// DOING OTHER STUFF HERE
fmt.Println(`m1`)
done := make(chan interface{})
terminated := make(chan interface{})
go pm.watchDir(done, terminated, nil)
fmt.Println(`m2.pre-10`)
time.Sleep(10 * time.Second)
fmt.Println(`m3-post-10`)
go pm.cancelWatchDir(done)
fmt.Println(`m4`)
<-terminated
fmt.Println(`m5`)
os.Exit(0) // Temporary for testing
return Err
}
func (pm *PluginManager) cancelWatchDir(done chan interface{}) {
fmt.Println(`t1`)
time.Sleep(5 * time.Second)
fmt.Println()
fmt.Println(`t2`)
close(done)
}
func (pm *PluginManager) watchDir(done <-chan interface{}, terminated chan interface{}, strings <-chan string) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
Logger("watchDir::"+err.Error(), `plugins`, Error)
}
//err = watcher.Add(pm.pluginDir)
err = watcher.Add(`/srv/plugins/`)
if err != nil {
Logger("watchDir::"+err.Error(), `plugins`, Error)
}
var tmr = time.NewTimer(time.Second)
tmr.Stop()
defer close(terminated)
defer watcher.Close()
defer tmr.Stop()
for {
select {
case <-tmr.C:
fmt.Println(`UPDATE FIRED`)
tmr.Stop()
case _, ok := <-watcher.Events:
if !ok {
return
}
fmt.Println(`Ticker: STOP`)
/*
* START OF ALTERNATIVES
*
* THIS IS BY EXAMPLE AND STATED THAT IT "MUST BE" AT:
* https://golang.org/pkg/time/#Timer.Reset
*
* BUT DOESN'T WORK
*/
if !tmr.Stop() {
fmt.Println(`Ticker: CHAN DRAIN`)
<-tmr.C // STOPS HERE AND GOES NO FURTHER
}
/*
* BUT IF I JUST DO THIS IT WORKS
*/
tmr.Stop()
/*
* END OF ALTERNATIVES
*/
fmt.Println(`Ticker: RESET`)
tmr.Reset(time.Second)
case <-done:
fmt.Println(`DONE TRIGGERED`)
return
}
}
}