github.com/status-im/status-go@v1.1.0/services/accounts/settingsevent/watcher.go (about) 1 package settingsevent 2 3 import ( 4 "context" 5 6 "github.com/ethereum/go-ethereum/event" 7 "github.com/ethereum/go-ethereum/log" 8 "github.com/status-im/status-go/multiaccounts/settings" 9 "github.com/status-im/status-go/services/wallet/async" 10 ) 11 12 type SettingChangeCb func(setting settings.SettingField, value interface{}) 13 14 // Watcher executes a given callback whenever an account gets added/removed 15 type Watcher struct { 16 feed *event.Feed 17 group *async.Group 18 callback SettingChangeCb 19 } 20 21 func NewWatcher(feed *event.Feed, callback SettingChangeCb) *Watcher { 22 return &Watcher{ 23 feed: feed, 24 callback: callback, 25 } 26 } 27 28 func (w *Watcher) Start() { 29 if w.group != nil { 30 return 31 } 32 33 w.group = async.NewGroup(context.Background()) 34 w.group.Add(func(ctx context.Context) error { 35 return watch(ctx, w.feed, w.callback) 36 }) 37 } 38 39 func (w *Watcher) Stop() { 40 if w.group != nil { 41 w.group.Stop() 42 w.group.Wait() 43 w.group = nil 44 } 45 } 46 47 func onSettingChanged(callback SettingChangeCb, setting settings.SettingField, value interface{}) { 48 if callback != nil { 49 callback(setting, value) 50 } 51 } 52 53 func watch(ctx context.Context, feed *event.Feed, callback SettingChangeCb) error { 54 ch := make(chan Event, 1) 55 sub := feed.Subscribe(ch) 56 defer sub.Unsubscribe() 57 58 for { 59 select { 60 case <-ctx.Done(): 61 return nil 62 case err := <-sub.Err(): 63 if err != nil { 64 log.Error("settings watcher subscription failed", "error", err) 65 } 66 case ev := <-ch: 67 if ev.Type == EventTypeChanged { 68 onSettingChanged(callback, ev.Setting, ev.Value) 69 } 70 } 71 } 72 }