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  }