accounts/keystore: New attempt to handle fs scanning events

This commit is contained in:
Martin Holst Swende 2017-09-09 21:55:16 +02:00
parent 79f83be3a6
commit 9a2db6e9f9

View file

@ -21,8 +21,10 @@ package keystore
import ( import (
"time" "time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/rjeczalik/notify" "github.com/rjeczalik/notify"
"sync/atomic"
) )
type watcher struct { type watcher struct {
@ -82,9 +84,10 @@ func (w *watcher) loop() {
// When an event occurs, the reload call is delayed a bit so that // When an event occurs, the reload call is delayed a bit so that
// multiple events arriving quickly only cause a single reload. // multiple events arriving quickly only cause a single reload.
var ( var (
debounce = time.NewTimer(0) debounce = time.NewTimer(0)
debounceDuration = 500 * time.Millisecond debounceDuration = 500 * time.Millisecond
inCycle, hadEvent bool unHandledEvents = uint64(0)
inCycle = uint64(0)
) )
defer debounce.Stop() defer debounce.Stop()
for { for {
@ -92,24 +95,28 @@ func (w *watcher) loop() {
case <-w.quit: case <-w.quit:
return return
case <-w.ev: case <-w.ev:
if !inCycle { // Count up the unhandled events
atomic.AddUint64(&unHandledEvents, 1)
// Trigger the scan (with delay), if not already triggered
if atomic.SwapUint64(&inCycle, 1) == 0 {
debounce.Reset(debounceDuration) debounce.Reset(debounceDuration)
inCycle = true
} else {
hadEvent = true
} }
case <-debounce.C: case <-debounce.C:
hadEvent = false //We're now handling the events, scan again as long as new
accounts, err := w.ac.scan() // events keep coming during our fs-scan
w.ac.mu.Lock() var (
w.ac.handleScanResult(accounts, err) accs []accounts.Account
w.ac.mu.Unlock() err error
if hadEvent { )
debounce.Reset(debounceDuration) // Scan again if more events occurred during scan
inCycle, hadEvent = true, false for atomic.SwapUint64(&unHandledEvents, 0) > 0 {
} else { accs, err = w.ac.scan()
inCycle, hadEvent = false, false
} }
w.ac.mu.Lock()
w.ac.handleScanResult(accs, err)
w.ac.mu.Unlock()
// Signal we're finished with cycle
atomic.SwapUint64(&inCycle, 0)
} }
} }
} }