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

     1  package walletevent
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/ethereum/go-ethereum/event"
     7  	"github.com/ethereum/go-ethereum/log"
     8  
     9  	"github.com/status-im/status-go/signal"
    10  )
    11  
    12  type Publisher interface {
    13  	Subscribe(interface{}) event.Subscription
    14  }
    15  
    16  // SignalsTransmitter transmits received events as wallet signals.
    17  type SignalsTransmitter struct {
    18  	Publisher
    19  
    20  	wg   sync.WaitGroup
    21  	quit chan struct{}
    22  }
    23  
    24  // Start runs loop in background.
    25  func (tmr *SignalsTransmitter) Start() error {
    26  	if tmr.quit != nil {
    27  		// already running, nothing to do
    28  		return nil
    29  	}
    30  	tmr.quit = make(chan struct{})
    31  	events := make(chan Event, 10)
    32  	sub := tmr.Publisher.Subscribe(events)
    33  
    34  	tmr.wg.Add(1)
    35  	go func() {
    36  		defer tmr.wg.Done()
    37  		for {
    38  			select {
    39  			case <-tmr.quit:
    40  				sub.Unsubscribe()
    41  				return
    42  			case err := <-sub.Err():
    43  				// technically event.Feed cannot send an error to subscription.Err channel.
    44  				// the only time we will get an event is when that channel is closed.
    45  				if err != nil {
    46  					log.Error("wallet signals transmitter failed with", "error", err)
    47  				}
    48  				return
    49  			case event := <-events:
    50  				if !event.Type.IsInternal() {
    51  					signal.SendWalletEvent(signal.Wallet, event)
    52  				}
    53  			}
    54  		}
    55  	}()
    56  	return nil
    57  }
    58  
    59  // Stop stops the loop and waits till it exits.
    60  func (tmr *SignalsTransmitter) Stop() {
    61  	if tmr.quit == nil {
    62  		return
    63  	}
    64  	close(tmr.quit)
    65  	tmr.wg.Wait()
    66  	tmr.quit = nil
    67  }