// Package handler provides HTTP handlers for various endpoints. package handler import ( "fmt" "net/http" "sync" "modelRT/constants" "modelRT/logger" "modelRT/network" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" ) var globalMonitorState *SharedMonitorState func init() { globalMonitorState = NewSharedMonitorState() } // RealTimeMonitorHandler define real time data monitor process API // @Summary 开始或结束实时数据监控 // @Description 根据用户输入的组件token,从 modelRT 服务中开始或结束对于实时数据的监控 // @Tags RealTime Component // @Accept json // @Produce json // @Router /data/realtime [get] func RealTimeMonitorHandler(c *gin.Context) { var request network.RealTimeQueryRequest var monitorAction string var monitorID string if err := c.ShouldBindJSON(&request); err != nil { logger.Error(c, "failed to unmarshal real time query request", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), }) return } if request.Action == constants.MonitorStartAction && request.MonitorID == "" { monitorAction = request.Action id, err := uuid.NewV4() if err != nil { logger.Error(c, "failed to generate monitor id", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), }) return } monitorID = id.String() } else if request.Action == constants.MonitorStartAction && request.MonitorID != "" { monitorAction = constants.MonitorAppendAction monitorID = request.MonitorID } else if request.Action == constants.MonitorStopAction && request.MonitorID != "" { monitorAction = request.Action monitorID = request.MonitorID } switch monitorAction { case constants.MonitorStartAction: fmt.Println(monitorID) var config RealTimeMonitorConfig for _, component := range request.Components { fmt.Println(config) globalMonitorState.Get(monitorID, component.Interval) } case constants.MonitorStopAction: for _, component := range request.Components { fmt.Println(component.Interval) } case constants.MonitorAppendAction: for _, component := range request.Components { fmt.Println(component.Interval) } default: err := fmt.Errorf("%w: %s", constants.ErrUnsupportedAction, request.Action) logger.Error(c, "unsupported action of real time data monitor request", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), }) return } } // RealTimeMonitorComponent define struct of real time monitor component type RealTimeMonitorComponent struct { interval string targets []string } // RealTimeMonitorConfig define struct of real time monitor config type RealTimeMonitorConfig struct { noticeChan chan struct{} components map[string]*RealTimeMonitorComponent } // SharedMonitorState define struct of shared monitor state with mutex type SharedMonitorState struct { monitorMap map[string]*RealTimeMonitorConfig mutex sync.RWMutex } // NewSharedMonitorState define function to create new SharedMonitorState func NewSharedMonitorState() *SharedMonitorState { return &SharedMonitorState{ monitorMap: make(map[string]*RealTimeMonitorConfig), } } // Set defined function to set value in SharedMonitorState func (s *SharedMonitorState) Set(key string, value *RealTimeMonitorConfig) { s.mutex.Lock() defer s.mutex.Unlock() s.monitorMap[key] = value } // Get defined function to get value from SharedMonitorState func (s *SharedMonitorState) Get(monitorID, interval string) ([]string, bool) { s.mutex.RLock() defer s.mutex.RUnlock() config, ok := s.monitorMap[monitorID] if !ok { return nil, false } component, ok := config.components[interval] if !ok { return nil, false } return component.targets, true }