cml04-printer-robot/internal/app/app.go
aespinro 9dece8deba wip
2024-08-19 02:23:44 +02:00

127 lines
3.1 KiB
Go

package app
import (
"flag"
"net"
"os"
"os/signal"
"syscall"
"git.espin.casa/albert/cml04-printer-robot/internal/logging"
"git.espin.casa/albert/cml04-printer-robot/internal/server"
"git.espin.casa/albert/cml04-printer-robot/internal/service"
"git.espin.casa/albert/cml04-printer-robot/internal/vnode"
"git.espin.casa/albert/cml04-printer-robot/pkg/api"
"git.espin.casa/albert/logger"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
func Run() error {
// flags
apiAddr := flag.String("api", "localhost:3333", "API server address")
logLevel := flag.String("level", "debug", "log level")
mqttAddr := flag.String("mqtt_addr", "tcp://10.1.152.13:1883", "MQTT address")
mqttTopic := flag.String("mqtt_topic", "vnode/ata12/robot", "MQTT topic")
// parse flags
flag.Parse()
// setup logger
log := logger.New(os.Stdout, *logLevel)
// create log fields
logFields := logger.LogFields{
"app_name": "cml04-printer-robot",
"debug_legel": *logLevel,
"mqtt_address": *mqttAddr,
"api_bind_address": *apiAddr,
}
// create broker
broker, err := vnode.NewBroker(*mqttAddr, log)
if err != nil {
log.Error("create new broker failed", err, logFields)
return err
}
// start broker
if err := broker.Connect(); err != nil {
log.Error("start broker failed", err, logFields)
return err
}
defer broker.Close()
// create main service
svc := service.NewService(broker)
// add logging capabilities to main service
svc = logging.NewLoggingService(svc, log)
// create data channel
dataChannel := make(chan []byte)
// create error channel
errorCallback := make(chan error)
// create done channel
done := make(chan struct{})
// subscribe robot data topic
go broker.SubscribeToMQTTTopic(*mqttTopic, dataChannel, errorCallback, done)
// get data from channel
go func() {
for {
select {
case data := <-dataChannel:
if err := svc.RobotEventDataHandler(data); err != nil {
log.Error("error robot event handler", err, logFields)
}
case err := <-errorCallback:
log.Error("error callback", err, logFields)
case <-done:
log.Info("done callback", logFields)
}
}
}()
// create grpc server
s := grpc.NewServer()
// create api server transport
server := server.NewAPIServer(svc)
// register service
api.RegisterRobotServiceServer(s, server)
// Reflection grpc server
reflection.Register(s)
// create grpc server
lis, err := net.Listen("tcp", *apiAddr)
if err != nil {
log.Error("failed to listen", err, logFields)
return err
}
// start service server
go func() {
if err := s.Serve(lis); err != nil {
log.Error("failed to serve gRPC", err, logFields)
return
}
}()
// start banner
log.Info("cml04 printer robot service started", logFields)
// wait signal to finish
signal := WaitSignal()
// end subscriber
close(done)
log.Info("signal received", logger.LogFields{
"signal": signal,
})
return nil
}
// WaitSignal catching exit signal
func WaitSignal() os.Signal {
ch := make(chan os.Signal, 2)
signal.Notify(
ch,
syscall.SIGINT,
syscall.SIGQUIT,
syscall.SIGTERM,
)
for {
sig := <-ch
switch sig {
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM:
return sig
}
}
}