github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/accounts/keystore/watch.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  //+建立达尔文,!iOS Freebsd Linux,!ARM64 NetBSD Solaris
    26  
    27  package keystore
    28  
    29  import (
    30  	"time"
    31  
    32  	"github.com/ethereum/go-ethereum/log"
    33  	"github.com/rjeczalik/notify"
    34  )
    35  
    36  type watcher struct {
    37  	ac       *accountCache
    38  	starting bool
    39  	running  bool
    40  	ev       chan notify.EventInfo
    41  	quit     chan struct{}
    42  }
    43  
    44  func newWatcher(ac *accountCache) *watcher {
    45  	return &watcher{
    46  		ac:   ac,
    47  		ev:   make(chan notify.EventInfo, 10),
    48  		quit: make(chan struct{}),
    49  	}
    50  }
    51  
    52  //在后台启动观察程序循环。
    53  //如果尚未进行,请在后台启动观察程序。
    54  //呼叫方必须持有W.AC.MU。
    55  func (w *watcher) start() {
    56  	if w.starting || w.running {
    57  		return
    58  	}
    59  	w.starting = true
    60  	go w.loop()
    61  }
    62  
    63  func (w *watcher) close() {
    64  	close(w.quit)
    65  }
    66  
    67  func (w *watcher) loop() {
    68  	defer func() {
    69  		w.ac.mu.Lock()
    70  		w.running = false
    71  		w.starting = false
    72  		w.ac.mu.Unlock()
    73  	}()
    74  	logger := log.New("path", w.ac.keydir)
    75  
    76  	if err := notify.Watch(w.ac.keydir, w.ev, notify.All); err != nil {
    77  		logger.Trace("Failed to watch keystore folder", "err", err)
    78  		return
    79  	}
    80  	defer notify.Stop(w.ev)
    81  	logger.Trace("Started watching keystore folder")
    82  	defer logger.Trace("Stopped watching keystore folder")
    83  
    84  	w.ac.mu.Lock()
    85  	w.running = true
    86  	w.ac.mu.Unlock()
    87  
    88  //等待文件系统事件并重新加载。
    89  //当事件发生时,重新加载调用会延迟一点,以便
    90  //多个事件快速到达只会导致一次重新加载。
    91  	var (
    92  		debounceDuration = 500 * time.Millisecond
    93  		rescanTriggered  = false
    94  		debounce         = time.NewTimer(0)
    95  	)
    96  //忽略初始触发器
    97  	if !debounce.Stop() {
    98  		<-debounce.C
    99  	}
   100  	defer debounce.Stop()
   101  	for {
   102  		select {
   103  		case <-w.quit:
   104  			return
   105  		case <-w.ev:
   106  //触发扫描(延迟),如果尚未触发
   107  			if !rescanTriggered {
   108  				debounce.Reset(debounceDuration)
   109  				rescanTriggered = true
   110  			}
   111  		case <-debounce.C:
   112  			w.ac.scanAccounts()
   113  			rescanTriggered = false
   114  		}
   115  	}
   116  }