status-go/services/wallet/transmitter.go
Andrea Maria Piana 435eacecb5 Handle wallet initialization
StartWallet was called before service initialization.
After the recent changes this call was moved after initialization, but
the geth system automatically start services.
This meant that `IsStarted()` returned true, although the reactor was
not started, and only after calling `StopWallet()` and `StartWallet()`
again the system would reach the right state.

This commit changes the behavior so that we only check whether the
reactor has been started when calling `IsStarted()` and we allow
multiple calls to `Start()` on the signal service, which won't return an
error (it's a noop if callled multiple times).
2020-08-18 14:13:08 +02:00

66 lines
1.3 KiB
Go

package wallet
import (
"sync"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/signal"
)
type publisher interface {
Subscribe(interface{}) event.Subscription
}
// SignalsTransmitter transmits received events as wallet signals.
type SignalsTransmitter struct {
publisher
wg sync.WaitGroup
quit chan struct{}
}
// Start runs loop in background.
func (tmr *SignalsTransmitter) Start() error {
if tmr.quit != nil {
// already running, nothing to do
return nil
}
tmr.quit = make(chan struct{})
events := make(chan Event, 10)
sub := tmr.publisher.Subscribe(events)
tmr.wg.Add(1)
go func() {
defer tmr.wg.Done()
for {
select {
case <-tmr.quit:
sub.Unsubscribe()
return
case err := <-sub.Err():
// technically event.Feed cannot send an error to subscription.Err channel.
// the only time we will get an event is when that channel is closed.
if err != nil {
log.Error("wallet signals transmitter failed with", "error", err)
}
return
case event := <-events:
signal.SendWalletEvent(event)
}
}
}()
return nil
}
// Stop stops the loop and waits till it exits.
func (tmr *SignalsTransmitter) Stop() {
if tmr.quit == nil {
return
}
close(tmr.quit)
tmr.wg.Wait()
tmr.quit = nil
}