modelRT/handler/real_time_data_monitor.go

140 lines
3.8 KiB
Go

// 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
}