github.com/status-im/status-go@v1.1.0/services/subscriptions/subscriptions.go (about)

     1  package subscriptions
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/ethereum/go-ethereum/log"
     9  )
    10  
    11  type Subscriptions struct {
    12  	mu          sync.Mutex
    13  	subs        map[SubscriptionID]*Subscription
    14  	checkPeriod time.Duration
    15  	log         log.Logger
    16  }
    17  
    18  func NewSubscriptions(period time.Duration) *Subscriptions {
    19  	return &Subscriptions{
    20  		subs:        make(map[SubscriptionID]*Subscription),
    21  		checkPeriod: period,
    22  		log:         log.New("package", "status-go/services/subsriptions.Subscriptions"),
    23  	}
    24  }
    25  
    26  func (s *Subscriptions) Create(namespace string, filter filter) (SubscriptionID, error) {
    27  	s.mu.Lock()
    28  	defer s.mu.Unlock()
    29  
    30  	newSub := NewSubscription(namespace, filter)
    31  
    32  	go func() {
    33  		err := newSub.Start(s.checkPeriod)
    34  		if err != nil {
    35  			s.log.Error("error while starting subscription", "err", err)
    36  		}
    37  	}()
    38  
    39  	s.subs[newSub.id] = newSub
    40  
    41  	return newSub.id, nil
    42  }
    43  
    44  func (s *Subscriptions) Remove(id SubscriptionID) error {
    45  	s.mu.Lock()
    46  	defer s.mu.Unlock()
    47  
    48  	found, err := s.stopSubscription(id, true)
    49  	if found {
    50  		delete(s.subs, id)
    51  	}
    52  
    53  	return err
    54  }
    55  
    56  func (s *Subscriptions) removeAll() error {
    57  	s.mu.Lock()
    58  	defer s.mu.Unlock()
    59  
    60  	unsubscribeErrors := make(map[SubscriptionID]error)
    61  
    62  	for id := range s.subs {
    63  		_, err := s.stopSubscription(id, false)
    64  		if err != nil {
    65  			unsubscribeErrors[id] = err
    66  		}
    67  	}
    68  
    69  	s.subs = make(map[SubscriptionID]*Subscription)
    70  
    71  	if len(unsubscribeErrors) > 0 {
    72  		return fmt.Errorf("errors while cleaning up subscriptions: %+v", unsubscribeErrors)
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  func (s *Subscriptions) stopSubscription(id SubscriptionID, uninstall bool) (bool, error) {
    79  	sub, found := s.subs[id]
    80  	if !found {
    81  		return false, nil
    82  	}
    83  	return true, sub.Stop(uninstall)
    84  }