package server import ( "fmt" "time" "context" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" pb "FRMS/internal/pkg/grpc" ) // this package will implement a reactor coordinator and associated go routines type ReactorCoordinator struct { Server *ReactorListener // embedding parent listener to call methods Ip string Port int Id uint32 Model string MaxAttempts int } func NewReactorCoordinator(s *ReactorListener, ip, model string, port int, id uint32) *ReactorCoordinator { return &ReactorCoordinator{Server: s, Ip: ip, Port: port, Id: id, Model: model,MaxAttempts:3} } func(r *ReactorCoordinator) Start() { // establish connection with reactor and start pinging at set intervals var opts []grpc.DialOption opts = append(opts,grpc.WithTransportCredentials(insecure.NewCredentials())) go r.Monitor(opts) } func (r *ReactorCoordinator) Exit() { // exit function to eventually allow saving to configs fmt.Printf("Reactor %v exiting", r.Id) } func (r *ReactorCoordinator) Monitor(opts []grpc.DialOption) { retry := 0 conn, err := grpc.Dial(fmt.Sprintf("%v:%v",r.Ip,r.Port),opts...) if err != nil { r.Server.Err <-err } defer conn.Close() client := pb.NewMonitoringClient(conn) for true { req := &pb.SensorStatusRequest{Id:r.Id} //time.Sleep(5*time.Second) resp, err := client.SensorStatusHandler(context.Background(),req) fmt.Println(resp,err) ok := true if err != nil { ok = false r.Server.Err <-err } if ok { fmt.Printf("Reactor %v at %v has %v devices connected:\n %v\n",r.Model, r.Ip, len(resp.GetSensors()), resp.GetSensors()) retry = 0 } else if retry >= r.MaxAttempts { // ran out of attempts to connect; killing fmt.Printf("Reactor %v at %v Down! Exiting Coordinator",r.Id,r.Ip) r.Exit() return }else { retry++ fmt.Printf("Reactor %v at %v ping failed, retrying %v time(s)",r.Model,r.Ip, r.MaxAttempts-retry) } time.Sleep(10 * time.Second) } }