package server import ( //"log" "time" "math" "sync" "errors" _ "context" "FRMS/internal/pkg/logging" ) // this package will implement a boilerplate manager // manager connects to client on start and returns the gRPC connection to make gRPC clients type Manager struct { *Client // gives access to c.Ip c.Id etc Hb time.Duration // used for managing hb timer for client Active active Sig chan bool Err chan error } type active struct{ sync.Mutex bool int } func NewManager(err chan error) *Manager { hb := time.Duration(1 * time.Second) //hb to m := &Manager{Hb:hb,Err:err} return m } func (m *Manager) Start() { if !m.Activate() { // manager already running m.Err <-errors.New("Manager already running!") } // if we get here, manager is atomically activated and we can ensure start wont run again } func (m *Manager) Exit() { // exit function to eventually allow saving to configs if !m.Deactivate() { m.Err <-errors.New("Manager already disabled!") } } func (m *Manager) UpdateClient(cl *Client) { logging.Debug(logging.DClient,"MAN Updating client %v",cl.Id) m.Client = cl } // reactor manager atomic operations func (m *Manager) IsActive() bool { m.Active.Lock() defer m.Active.Unlock() return m.Active.bool } func (m *Manager) Activate() bool { // slightly confusing but returns result of trying to activate m.Active.Lock() defer m.Active.Unlock() alive := m.Active.bool if alive { return false } else { m.Active.bool = true m.Active.int = 0 return m.Active.bool } } func (m *Manager) Deactivate() bool { // result of trying to deactivate m.Active.Lock() defer m.Active.Unlock() alive := m.Active.bool if alive { m.Active.bool = false return true } else { return m.Active.bool } } // connection stuff func (m *Manager) Timeout() int { // keeps track of and generates timeout [0-1.2s) over span of ~2.5s // returns 0 on TO elapse m.Active.Lock() defer m.Active.Unlock() if m.Active.int < 9 { v := int(5 * math.Pow(float64(2), float64(m.Active.int))) m.Active.int += 1 return v } else { // exceeded retries return 0 } } /* shouldnt be nessecary anymore func (m *Manager) GetDevices(ctx context.Context, req *pb.GetDevicesRequest) (*pb.GetDevicesResponse, error) { return &pb.GetDevicesResponse{}, errors.New("Get Devices not implemented!") } func (m *Manager) ReactorStatusHandler(ctx context.Context, req *pb.ReactorStatusPing) (*pb.ReactorStatusResponse, error) { return &pb.ReactorStatusResponse{}, errors.New("Reactor Status Handler not implemented!") } */