Services lifetime

<aside> ☝

NOTE: By service I mean any long-living object, it could be just a module/server/etc.

</aside>

To control a service, use this approach:

type Service struct {
	quit chan struct{}
	wg   sync.WaitGroup
}

// Run should be a blocking call. 
// To stop it, call Stop.
func (s *Service) Run() {
	ctx, cancel := context.WithCancel(context.Background())
	
	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		s.worker.Start()
	}()
	
	defer s.worker.Stop()

	s.wg.Wait()
}

func (s *Service) Stop() {
	s.quit <- struct{}{}
}

func (s *Service) Work(ctx context.Context) {
	ctx, cancel := context.WithCancel(ctx)
	go func() {
		case <-s.quit:
			cancel()
	}()
	
	work(ctx)
}

By forcing Run to be a blocking call, we ensure:

History

https://github.com/status-im/status-go/pull/3768