github.com/status-im/status-go@v1.1.0/services/wallet/walletevent/watcher.go (about)

     1  package walletevent
     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/services/wallet/async"
     9  )
    10  
    11  type EventCb func(event Event)
    12  
    13  // Watcher executes a given callback whenever a wallet event gets sent
    14  type Watcher struct {
    15  	feed     *event.Feed
    16  	group    *async.Group
    17  	callback EventCb
    18  }
    19  
    20  func NewWatcher(feed *event.Feed, callback EventCb) *Watcher {
    21  	return &Watcher{
    22  		feed:     feed,
    23  		callback: callback,
    24  	}
    25  }
    26  
    27  func (w *Watcher) Start() {
    28  	if w.group != nil {
    29  		return
    30  	}
    31  
    32  	w.group = async.NewGroup(context.Background())
    33  	w.group.Add(func(ctx context.Context) error {
    34  		return watch(ctx, w.feed, w.callback)
    35  	})
    36  }
    37  
    38  func (w *Watcher) Stop() {
    39  	if w.group != nil {
    40  		w.group.Stop()
    41  		w.group.Wait()
    42  		w.group = nil
    43  	}
    44  }
    45  
    46  func watch(ctx context.Context, feed *event.Feed, callback EventCb) error {
    47  	ch := make(chan Event, 10)
    48  	sub := feed.Subscribe(ch)
    49  	defer sub.Unsubscribe()
    50  
    51  	for {
    52  		select {
    53  		case <-ctx.Done():
    54  			return nil
    55  		case err := <-sub.Err():
    56  			if err != nil {
    57  				log.Error("wallet event watcher subscription failed", "error", err)
    58  			}
    59  		case ev := <-ch:
    60  			if callback != nil {
    61  				callback(ev)
    62  			}
    63  		}
    64  	}
    65  }