Skip to content
Snippets Groups Projects
Select Git revision
  • development
  • main default protected
  • integration
  • v1.1.5
  • v1.1.4
  • v1.1.3
  • v1.1.2
  • v1.1.1
  • v1.1.0
  • v1.0.0
10 results

MessengerStartTests.swift

Blame
  • services.go NaN GiB
    package api
    
    import (
    	"github.com/pkg/errors"
    	"gitlab.com/elixxir/client/stoppable"
    	"sync"
    	"time"
    )
    
    // a service process starts itself in a new thread, returning from the
    // originator a stopable to control it
    type Service func() (stoppable.Stoppable, error)
    
    type services struct {
    	services  []Service
    	stoppable *stoppable.Multi
    	state     Status
    	mux       sync.Mutex
    }
    
    // newServiceProcessiesList creates a new services list which will add its
    // services to the passed mux
    func newServices() *services {
    	return &services{
    		services:  make([]Service, 0),
    		stoppable: stoppable.NewMulti("services"),
    		state:     Stopped,
    	}
    }
    
    // Add adds the service process to the list and adds it to the multi-stopable.
    // Start running it if services are running
    func (s *services) add(sp Service) error {
    	s.mux.Lock()
    	defer s.mux.Unlock()
    
    	//append the process to the list
    	s.services = append(s.services, sp)
    
    	//if services are running, start the process
    	if s.state == Running {
    		stop, err := sp()
    		if err != nil {
    			return errors.WithMessage(err, "Failed to start added service")
    		}
    		s.stoppable.Add(stop)
    	}
    	return nil
    }
    
    // Runs all services. If they are in the process of stopping,
    // it will wait for the stop to complete or the timeout to ellapse
    // Will error if already running
    func (s *services) start(timeout time.Duration) error {
    	s.mux.Lock()
    	defer s.mux.Unlock()
    
    	//handle various states
    	switch s.state {
    	case Stopped:
    		break
    	case Running:
    		return errors.New("Cannot start services when already Running")
    	case Stopping:
    		err := stoppable.WaitForStopped(s.stoppable, timeout)
    		if err != nil {
    			return errors.Errorf("Procesies did not all stop within %s, "+
    				"unable to start services: %+v", timeout, err)
    		}
    	}
    
    	//create a new stopable
    	s.stoppable = stoppable.NewMulti(followerStoppableName)
    
    	//start all services and register with the stoppable
    	for _, sp := range s.services {
    		stop, err := sp()
    		if err != nil {
    			return errors.WithMessage(err, "Failed to start added service")
    		}
    		s.stoppable.Add(stop)
    	}
    
    	s.state = Running
    
    	return nil
    }
    
    // Stops all currently running services. Will return an
    // error if the state is not "running"
    func (s *services) stop() error {
    	s.mux.Lock()
    	defer s.mux.Unlock()
    
    	if s.state != Running {
    		return errors.Errorf("cannot stop services when they "+
    			"are not Running, services are: %s", s.state)
    	}
    
    	s.state = Stopping
    
    	if err := s.stoppable.Close(); err != nil {
    		return errors.WithMessage(err, "Failed to stop services")
    	}
    
    	s.state = Stopped
    
    	return nil
    }
    
    // returns the current state of services
    func (s *services) status() Status {
    	s.mux.Lock()
    	defer s.mux.Unlock()
    
    	return s.state
    }