github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/accounts/keystore/watch.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:27</date> 10 //</624342586072502272> 11 12 13 //+建立达尔文,!iOS Freebsd Linux,!ARM64 NetBSD Solaris 14 15 package keystore 16 17 import ( 18 "time" 19 20 "github.com/ethereum/go-ethereum/log" 21 "github.com/rjeczalik/notify" 22 ) 23 24 type watcher struct { 25 ac *accountCache 26 starting bool 27 running bool 28 ev chan notify.EventInfo 29 quit chan struct{} 30 } 31 32 func newWatcher(ac *accountCache) *watcher { 33 return &watcher{ 34 ac: ac, 35 ev: make(chan notify.EventInfo, 10), 36 quit: make(chan struct{}), 37 } 38 } 39 40 //在后台启动观察程序循环。 41 //如果尚未进行,请在后台启动观察程序。 42 //呼叫方必须持有W.AC.MU。 43 func (w *watcher) start() { 44 if w.starting || w.running { 45 return 46 } 47 w.starting = true 48 go w.loop() 49 } 50 51 func (w *watcher) close() { 52 close(w.quit) 53 } 54 55 func (w *watcher) loop() { 56 defer func() { 57 w.ac.mu.Lock() 58 w.running = false 59 w.starting = false 60 w.ac.mu.Unlock() 61 }() 62 logger := log.New("path", w.ac.keydir) 63 64 if err := notify.Watch(w.ac.keydir, w.ev, notify.All); err != nil { 65 logger.Trace("Failed to watch keystore folder", "err", err) 66 return 67 } 68 defer notify.Stop(w.ev) 69 logger.Trace("Started watching keystore folder") 70 defer logger.Trace("Stopped watching keystore folder") 71 72 w.ac.mu.Lock() 73 w.running = true 74 w.ac.mu.Unlock() 75 76 //等待文件系统事件并重新加载。 77 //当事件发生时,重新加载调用会延迟一点,以便 78 //多个事件快速到达只会导致一次重新加载。 79 var ( 80 debounceDuration = 500 * time.Millisecond 81 rescanTriggered = false 82 debounce = time.NewTimer(0) 83 ) 84 //忽略初始触发器 85 if !debounce.Stop() { 86 <-debounce.C 87 } 88 defer debounce.Stop() 89 for { 90 select { 91 case <-w.quit: 92 return 93 case <-w.ev: 94 //触发扫描(延迟),如果尚未触发 95 if !rescanTriggered { 96 debounce.Reset(debounceDuration) 97 rescanTriggered = true 98 } 99 case <-debounce.C: 100 w.ac.scanAccounts() 101 rescanTriggered = false 102 } 103 } 104 } 105