Select Git revision
MessengerStartTests.swift
-
Dariusz Rybicki authored
Remove MessengerContext
Dariusz Rybicki authoredRemove MessengerContext
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
}