optimize variable naming and optimize real time data computing api
This commit is contained in:
parent
b43adf9b67
commit
041d7e5788
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Package constants define constant variable
|
||||||
|
package constants
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SendMaxBatchSize define maximum buffer capacity
|
||||||
|
SendMaxBatchSize = 100
|
||||||
|
// SendMaxBatchInterval define maximum aggregate latency
|
||||||
|
SendMaxBatchInterval = 200 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
@ -35,7 +35,7 @@ func QueryAlertEventHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]any{
|
||||||
"events": events,
|
"events": events,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func ComponentAnchorReplaceHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": request.UUID,
|
"uuid": request.UUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ func AttrDeleteHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{"attr_token": request.AttrToken},
|
Payload: map[string]interface{}{"attr_token": request.AttrToken},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ func AttrDeleteHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"attr_token": request.AttrToken,
|
"attr_token": request.AttrToken,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ func AttrGetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{"attr_token": request.AttrToken},
|
Payload: map[string]interface{}{"attr_token": request.AttrToken},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ func AttrGetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"attr_token": request.AttrToken,
|
"attr_token": request.AttrToken,
|
||||||
"attr_value": attrValue,
|
"attr_value": attrValue,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ func AttrSetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{"attr_token": request.AttrToken},
|
Payload: map[string]interface{}{"attr_token": request.AttrToken},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ func AttrSetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"attr_token": request.AttrToken,
|
"attr_token": request.AttrToken,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicLink,
|
"topologic_info": topologicLink,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_infos": topologicCreateInfos,
|
"topologic_infos": topologicCreateInfos,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"component_infos": request.ComponentInfos,
|
"component_infos": request.ComponentInfos,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": info.UUID,
|
"uuid": info.UUID,
|
||||||
"component_params": info.Params,
|
"component_params": info.Params,
|
||||||
},
|
},
|
||||||
|
|
@ -152,7 +152,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicLink,
|
"topologic_info": topologicLink,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicDelInfo,
|
"topologic_info": topologicDelInfo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +112,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicDelInfo,
|
"topologic_info": topologicDelInfo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +138,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": componentInfo.UUID,
|
"uuid": componentInfo.UUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": componentInfo.UUID,
|
"uuid": componentInfo.UUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": componentInfo.UUID,
|
"uuid": componentInfo.UUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +205,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": pageID,
|
"page_id": pageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -48,16 +48,16 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": pageID,
|
"page_id": pageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
payLoad := make(map[string]interface{})
|
payload := make(map[string]interface{})
|
||||||
payLoad["root_vertex"] = topologicInfo.RootVertex
|
payload["root_vertex"] = topologicInfo.RootVertex
|
||||||
payLoad["topologic"] = topologicInfo.VerticeLinks
|
payload["topologic"] = topologicInfo.VerticeLinks
|
||||||
|
|
||||||
componentParamMap := make(map[string]any)
|
componentParamMap := make(map[string]any)
|
||||||
for _, VerticeLink := range topologicInfo.VerticeLinks {
|
for _, VerticeLink := range topologicInfo.VerticeLinks {
|
||||||
|
|
@ -69,7 +69,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": componentUUID,
|
"uuid": componentUUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +84,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": componentUUID,
|
"uuid": componentUUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +103,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": topologicInfo.RootVertex,
|
"uuid": topologicInfo.RootVertex,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": rootVertexUUID,
|
"uuid": rootVertexUUID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +127,12 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
componentParamMap[rootVertexUUID] = rootComponentParam
|
componentParamMap[rootVertexUUID] = rootComponentParam
|
||||||
|
|
||||||
payLoad["component_params"] = componentParamMap
|
payload["component_params"] = componentParamMap
|
||||||
|
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: payLoad,
|
Payload: payload,
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicLink,
|
"topologic_info": topologicLink,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +75,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicChangeInfo,
|
"topologic_info": topologicChangeInfo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"topologic_info": topologicChangeInfo,
|
"topologic_info": topologicChangeInfo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +109,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
"component_info": request.ComponentInfos,
|
"component_info": request.ComponentInfos,
|
||||||
},
|
},
|
||||||
|
|
@ -129,7 +129,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.FailureResponse{
|
resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"uuid": info.UUID,
|
"uuid": info.UUID,
|
||||||
"component_params": info.Params,
|
"component_params": info.Params,
|
||||||
},
|
},
|
||||||
|
|
@ -152,7 +152,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"page_id": request.PageID,
|
"page_id": request.PageID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ func QueryHistoryDataHandler(c *gin.Context) {
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"events": events,
|
"events": events,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ func MeasurementGetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"measurement_id": request.MeasurementID,
|
"measurement_id": request.MeasurementID,
|
||||||
"measurement_token": request.MeasurementToken,
|
"measurement_token": request.MeasurementToken,
|
||||||
},
|
},
|
||||||
|
|
@ -60,7 +60,7 @@ func MeasurementGetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"measurement_id": request.MeasurementID,
|
"measurement_id": request.MeasurementID,
|
||||||
"measurement_token": request.MeasurementToken,
|
"measurement_token": request.MeasurementToken,
|
||||||
"measurement_value": points,
|
"measurement_value": points,
|
||||||
|
|
@ -72,7 +72,7 @@ func MeasurementGetHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: map[string]interface{}{
|
Payload: map[string]interface{}{
|
||||||
"measurement_id": request.MeasurementID,
|
"measurement_id": request.MeasurementID,
|
||||||
"measurement_token": request.MeasurementToken,
|
"measurement_token": request.MeasurementToken,
|
||||||
"measurement_info": measurementInfo,
|
"measurement_info": measurementInfo,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
// @Tags Measurement Recommend
|
// @Tags Measurement Recommend
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param request body network.MeasurementRecommendRequest true "查询输入参数,例如 'trans' 或 'transformfeeder1_220.'"
|
// @Param。 input query string true "推荐关键词,例如 'trans' 或 'transformfeeder1_220.'" Example("trans")
|
||||||
// @Success 200 {object} network.SuccessResponse{payload=network.MeasurementRecommendPayload} "返回推荐列表成功"
|
// @Success 200 {object} network.SuccessResponse{payload=network.MeasurementRecommendPayload} "返回推荐列表成功"
|
||||||
//
|
//
|
||||||
// @Example 200 {
|
// @Example 200 {
|
||||||
|
|
@ -45,8 +45,8 @@ import (
|
||||||
func MeasurementRecommendHandler(c *gin.Context) {
|
func MeasurementRecommendHandler(c *gin.Context) {
|
||||||
var request network.MeasurementRecommendRequest
|
var request network.MeasurementRecommendRequest
|
||||||
|
|
||||||
if err := c.ShouldBindJSON(&request); err != nil {
|
if err := c.ShouldBindQuery(&request); err != nil {
|
||||||
logger.Error(c, "failed to unmarshal measurement recommend request", "error", err)
|
logger.Error(c, "failed to bind measurement recommend request", "error", err)
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
|
|
@ -60,7 +60,7 @@ func MeasurementRecommendHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: map[string]any{
|
Payload: map[string]any{
|
||||||
"input": request.Input,
|
"input": request.Input,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
@ -104,7 +104,7 @@ func MeasurementRecommendHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: &network.MeasurementRecommendPayload{
|
Payload: &network.MeasurementRecommendPayload{
|
||||||
Input: request.Input,
|
Input: request.Input,
|
||||||
Offset: finalOffset,
|
Offset: finalOffset,
|
||||||
RecommendedList: resultRecommends,
|
RecommendedList: resultRecommends,
|
||||||
|
|
|
||||||
|
|
@ -60,24 +60,51 @@ func PullRealTimeDataHandler(c *gin.Context) {
|
||||||
// TODO[BACKPRESSURE-ISSUE] 先期使用固定大容量对扇入模型进行定义 #1
|
// TODO[BACKPRESSURE-ISSUE] 先期使用固定大容量对扇入模型进行定义 #1
|
||||||
fanInChan := make(chan network.RealTimePullTarget, 10000)
|
fanInChan := make(chan network.RealTimePullTarget, 10000)
|
||||||
go processTargetPolling(ctx, globalMonitorState, clientID, fanInChan)
|
go processTargetPolling(ctx, globalMonitorState, clientID, fanInChan)
|
||||||
|
|
||||||
go readClientMessages(ctx, conn, clientID, cancel)
|
go readClientMessages(ctx, conn, clientID, cancel)
|
||||||
|
|
||||||
|
bufferMaxSize := constants.SendMaxBatchSize
|
||||||
|
sendMaxInterval := constants.SendMaxBatchInterval
|
||||||
|
buffer := make([]network.RealTimePullTarget, 0, bufferMaxSize)
|
||||||
|
ticker := time.NewTicker(sendMaxInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case targetData, ok := <-fanInChan:
|
case targetData, ok := <-fanInChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Error(ctx, "fanInChan closed unexpectedly", "clientID", clientID)
|
logger.Error(ctx, "fanInChan closed unexpectedly", "client_id", clientID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO 考虑后续将多个 targets 聚合发送
|
buffer = append(buffer, targetData)
|
||||||
err := sendRealTimeDataStream(conn, targetData)
|
|
||||||
if err != nil {
|
if len(buffer) >= bufferMaxSize {
|
||||||
logger.Error(nil, "clientID: %s 写入数据失败: %v", clientID, err)
|
// buffer is full, send immediately
|
||||||
|
if err := sendAggregateRealTimeDataStream(conn, buffer); err != nil {
|
||||||
|
logger.Error(nil, "when buffer is full, send the real time aggregate data failed", "client_id", clientID, "buffer", buffer, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// reset buffer
|
||||||
|
buffer = make([]network.RealTimePullTarget, 0, bufferMaxSize)
|
||||||
|
// reset the ticker to prevent it from triggering immediately after the ticker is sent
|
||||||
|
ticker.Reset(sendMaxInterval)
|
||||||
}
|
}
|
||||||
default:
|
case <-ticker.C:
|
||||||
// TODO[BACKPRESSURE-ISSUE] 考虑在此使用双重背压方式解决阻塞问题 #1
|
if len(buffer) > 0 {
|
||||||
logger.Warn(ctx, "Write channel full, dropping data for slow client.")
|
// when the ticker is triggered, all data in the send buffer is sent
|
||||||
|
if err := sendAggregateRealTimeDataStream(conn, buffer); err != nil {
|
||||||
|
logger.Error(nil, "when the ticker is triggered, send the real time aggregate data failed", "client_id", clientID, "buffer", buffer, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// reset buffer
|
||||||
|
buffer = make([]network.RealTimePullTarget, 0, bufferMaxSize)
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
// send the last remaining data
|
||||||
|
if err := sendAggregateRealTimeDataStream(conn, buffer); err != nil {
|
||||||
|
logger.Error(nil, "send the last remaining data failed", "client_id", clientID, "buffer", buffer, "error", err)
|
||||||
|
}
|
||||||
|
logger.Info(ctx, "PullRealTimeDataHandler exiting as context is done.", "client_id", clientID)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,13 +134,16 @@ func readClientMessages(ctx context.Context, conn *websocket.Conn, clientID stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendRealTimeDataStream define func to responsible for continuously pushing real-time data to the client
|
// sendAggregateRealTimeDataStream define func to responsible for continuously pushing aggregate real-time data to the client
|
||||||
func sendRealTimeDataStream(conn *websocket.Conn, targetData network.RealTimePullTarget) error {
|
func sendAggregateRealTimeDataStream(conn *websocket.Conn, targetsData []network.RealTimePullTarget) error {
|
||||||
|
if len(targetsData) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
response := network.SuccessResponse{
|
response := network.SuccessResponse{
|
||||||
Code: 200,
|
Code: 200,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: network.RealTimePullPayload{
|
Payload: network.RealTimePullPayload{
|
||||||
Targets: []network.RealTimePullTarget{targetData},
|
Targets: targetsData,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return conn.WriteJSON(response)
|
return conn.WriteJSON(response)
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -133,7 +133,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -146,7 +146,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -157,7 +157,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -170,7 +170,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -181,7 +181,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.SuccessResponse{
|
c.JSON(http.StatusOK, network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Msg: "success",
|
Msg: "success",
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
@ -195,7 +195,7 @@ func RealTimeSubHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, network.FailureResponse{
|
c.JSON(http.StatusOK, network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
PayLoad: network.RealTimeSubPayload{
|
Payload: network.RealTimeSubPayload{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
TargetResults: results,
|
TargetResults: results,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
19
main.go
19
main.go
|
|
@ -22,11 +22,11 @@ import (
|
||||||
"modelRT/middleware"
|
"modelRT/middleware"
|
||||||
"modelRT/model"
|
"modelRT/model"
|
||||||
"modelRT/pool"
|
"modelRT/pool"
|
||||||
|
realtimedata "modelRT/real-time-data"
|
||||||
"modelRT/router"
|
"modelRT/router"
|
||||||
"modelRT/util"
|
"modelRT/util"
|
||||||
|
|
||||||
realtimedata "modelRT/real-time-data"
|
"github.com/confluentinc/confluent-kafka-go/kafka"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
swaggerFiles "github.com/swaggo/files"
|
swaggerFiles "github.com/swaggo/files"
|
||||||
|
|
@ -146,11 +146,18 @@ func main() {
|
||||||
}
|
}
|
||||||
defer anchorRealTimePool.Release()
|
defer anchorRealTimePool.Release()
|
||||||
|
|
||||||
|
// TODO 配置文件中增加 kafka 配置
|
||||||
// init cancel context
|
// init cancel context
|
||||||
cancelCtx, cancel := context.WithCancel(ctx)
|
cancelCtx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
// init real time data receive channel
|
customerConf := &kafka.ConfigMap{
|
||||||
go realtimedata.ReceiveChan(cancelCtx)
|
"bootstrap.servers": modelRTConfig.KafkaConfig.Servers,
|
||||||
|
"group.id": modelRTConfig.KafkaConfig.GroupID,
|
||||||
|
"auto.offset.reset": modelRTConfig.KafkaConfig.AutoOffsetReset,
|
||||||
|
"enable.auto.commit": modelRTConfig.KafkaConfig.EnableAutoCommit,
|
||||||
|
}
|
||||||
|
|
||||||
|
go realtimedata.ReceiveChan(cancelCtx, customerConf, []string{modelRTConfig.KafkaConfig.Topic}, modelRTConfig.KafkaConfig.ReadMessageTimeDuration)
|
||||||
|
|
||||||
postgresDBClient.Transaction(func(tx *gorm.DB) error {
|
postgresDBClient.Transaction(func(tx *gorm.DB) error {
|
||||||
// load circuit diagram from postgres
|
// load circuit diagram from postgres
|
||||||
|
|
@ -170,10 +177,6 @@ func main() {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO 完成订阅数据分析
|
|
||||||
// TODO 暂时屏蔽完成 swagger 启动测试
|
|
||||||
// go realtimedata.RealTimeDataComputer(ctx, nil, []string{}, "")
|
|
||||||
|
|
||||||
// use release mode in productio
|
// use release mode in productio
|
||||||
// gin.SetMode(gin.ReleaseMode)
|
// gin.SetMode(gin.ReleaseMode)
|
||||||
engine := gin.New()
|
engine := gin.New()
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@ type MeasurementGetRequest struct {
|
||||||
|
|
||||||
// MeasurementRecommendRequest defines the request payload for an measurement recommend
|
// MeasurementRecommendRequest defines the request payload for an measurement recommend
|
||||||
type MeasurementRecommendRequest struct {
|
type MeasurementRecommendRequest struct {
|
||||||
Input string `json:"input" example:"trans"`
|
Input string `form:"input,omitempty" example:"trans"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@ package network
|
||||||
type FailureResponse struct {
|
type FailureResponse struct {
|
||||||
Code int `json:"code" example:"500"`
|
Code int `json:"code" example:"500"`
|
||||||
Msg string `json:"msg" example:"failed to get recommend data from redis"`
|
Msg string `json:"msg" example:"failed to get recommend data from redis"`
|
||||||
PayLoad any `json:"payload" swaggertype:"object"`
|
Payload any `json:"payload" swaggertype:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuccessResponse define struct of standard successful API response format
|
// SuccessResponse define struct of standard successful API response format
|
||||||
type SuccessResponse struct {
|
type SuccessResponse struct {
|
||||||
Code int `json:"code" example:"200"`
|
Code int `json:"code" example:"200"`
|
||||||
Msg string `json:"msg" example:"success"`
|
Msg string `json:"msg" example:"success"`
|
||||||
PayLoad any `json:"payload" swaggertype:"object"`
|
Payload any `json:"payload" swaggertype:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MeasurementRecommendPayload define struct of represents the data payload for the successful recommendation response.
|
// MeasurementRecommendPayload define struct of represents the data payload for the successful recommendation response.
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
// Package realtimedata define real time data operation functions
|
|
||||||
package realtimedata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"modelRT/logger"
|
|
||||||
|
|
||||||
"github.com/confluentinc/confluent-kafka-go/kafka"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RealTimeDataComputer continuously processing real-time data from Kafka specified topics
|
|
||||||
func RealTimeDataComputer(ctx context.Context, consumerConfig kafka.ConfigMap, topics []string, duration string) {
|
|
||||||
// context for graceful shutdown
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// setup a channel to listen for interrupt signals
|
|
||||||
// TODO 将中断信号放到入参中
|
|
||||||
interrupt := make(chan struct{}, 1)
|
|
||||||
|
|
||||||
// read message (-1 means wait indefinitely)
|
|
||||||
timeoutDuration, err := time.ParseDuration(duration)
|
|
||||||
|
|
||||||
// create a new consumer
|
|
||||||
consumer, err := kafka.NewConsumer(&consumerConfig)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(ctx, "init kafka consume by config failed", "config", consumerConfig, "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// subscribe to the topic
|
|
||||||
err = consumer.SubscribeTopics(topics, nil)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(ctx, "subscribe to the topic failed", "topic", topics, "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// start a goroutine to handle shutdown
|
|
||||||
go func() {
|
|
||||||
<-interrupt
|
|
||||||
cancel()
|
|
||||||
consumer.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// continuously read messages from Kafka
|
|
||||||
for {
|
|
||||||
msg, err := consumer.ReadMessage(timeoutDuration)
|
|
||||||
if err != nil {
|
|
||||||
if ctx.Err() == context.Canceled {
|
|
||||||
logger.Info(ctx, "context canceled, stopping read loop")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
logger.Error(ctx, "consumer read message failed", "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 使用 ants.pool处理 kafka 的订阅数据
|
|
||||||
_, err = consumer.CommitMessage(msg)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(ctx, "manual submission information failed", "message", msg, "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
// Package realtimedata define real time data operation functions
|
||||||
|
package realtimedata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"modelRT/config"
|
||||||
|
"modelRT/constants"
|
||||||
|
"modelRT/diagram"
|
||||||
|
"modelRT/logger"
|
||||||
|
"modelRT/network"
|
||||||
|
"modelRT/pool"
|
||||||
|
|
||||||
|
"github.com/confluentinc/confluent-kafka-go/kafka"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RealTimeDataChan define channel of real time data receive
|
||||||
|
var RealTimeDataChan chan network.RealTimeDataReceiveRequest
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RealTimeDataChan = make(chan network.RealTimeDataReceiveRequest, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveChan define func of real time data receive and process
|
||||||
|
func ReceiveChan(ctx context.Context, consumerConfig *kafka.ConfigMap, topics []string, duration string) {
|
||||||
|
fmt.Println(topics, duration)
|
||||||
|
consumer, err := kafka.NewConsumer(consumerConfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "create kafka consumer failed", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer consumer.Close()
|
||||||
|
|
||||||
|
err = consumer.SubscribeTopics(topics, nil)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "subscribe kafka topics failed", "topic", topics, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info(ctx, "start consuming from kafka", "topic", topics)
|
||||||
|
|
||||||
|
batchSize := 100
|
||||||
|
batchTimeout := 2 * time.Second
|
||||||
|
messages := make([]*kafka.Message, 0, batchSize)
|
||||||
|
lastCommit := time.Now()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case realTimeData := <-RealTimeDataChan:
|
||||||
|
componentUUID := realTimeData.PayLoad.ComponentUUID
|
||||||
|
component, err := diagram.GetComponentMap(componentUUID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "query component info from diagram map by componet id failed", "component_uuid", componentUUID, "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
componentType := component.Type
|
||||||
|
if componentType != constants.DemoType {
|
||||||
|
logger.Error(ctx, "can not process real time data of component type not equal DemoType", "component_uuid", componentUUID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var anchorName string
|
||||||
|
var compareValUpperLimit, compareValLowerLimit float64
|
||||||
|
var anchorRealTimeData []float64
|
||||||
|
var calculateFunc func(archorValue float64, args ...float64) float64
|
||||||
|
|
||||||
|
// calculateFunc, params := config.SelectAnchorCalculateFuncAndParams(componentType, anchorName, componentData)
|
||||||
|
|
||||||
|
for _, param := range realTimeData.PayLoad.Values {
|
||||||
|
anchorRealTimeData = append(anchorRealTimeData, param.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
anchorConfig := config.AnchorParamConfig{
|
||||||
|
AnchorParamBaseConfig: config.AnchorParamBaseConfig{
|
||||||
|
ComponentUUID: componentUUID,
|
||||||
|
AnchorName: anchorName,
|
||||||
|
CompareValUpperLimit: compareValUpperLimit,
|
||||||
|
CompareValLowerLimit: compareValLowerLimit,
|
||||||
|
AnchorRealTimeData: anchorRealTimeData,
|
||||||
|
},
|
||||||
|
CalculateFunc: calculateFunc,
|
||||||
|
CalculateParams: []float64{},
|
||||||
|
}
|
||||||
|
anchorChan, err := pool.GetAnchorParamChan(ctx, componentUUID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "get anchor param chan failed", "component_uuid", componentUUID, "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
anchorChan <- anchorConfig
|
||||||
|
default:
|
||||||
|
msg, err := consumer.ReadMessage(batchTimeout)
|
||||||
|
if err != nil {
|
||||||
|
if err.(kafka.Error).Code() == kafka.ErrTimedOut {
|
||||||
|
// 超时时处理累积的消息
|
||||||
|
if len(messages) > 0 {
|
||||||
|
processMessageBatch(ctx, messages)
|
||||||
|
consumer.Commit()
|
||||||
|
messages = messages[:0]
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logger.Error(ctx, "read message from kafka failed", "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
messages = append(messages, msg)
|
||||||
|
|
||||||
|
// TODO 达到批处理大小或超时时间时处理消息
|
||||||
|
if len(messages) >= batchSize || time.Since(lastCommit) >= batchTimeout {
|
||||||
|
processMessageBatch(ctx, messages)
|
||||||
|
consumer.Commit()
|
||||||
|
messages = messages[:0]
|
||||||
|
lastCommit = time.Now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RealTimeDataPayload struct {
|
||||||
|
ComponentUUID string
|
||||||
|
Values []float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type RealTimeData struct {
|
||||||
|
Payload RealTimeDataPayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseKafkaMessage(msgValue []byte) (*RealTimeData, error) {
|
||||||
|
var realTimeData RealTimeData
|
||||||
|
err := json.Unmarshal(msgValue, &realTimeData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("json unmarshal failed: %w", err)
|
||||||
|
}
|
||||||
|
return &realTimeData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func processRealTimeData(ctx context.Context, realTimeData *RealTimeData) {
|
||||||
|
componentUUID := realTimeData.Payload.ComponentUUID
|
||||||
|
component, err := diagram.GetComponentMap(componentUUID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "query component info from diagram map by component id failed",
|
||||||
|
"component_uuid", componentUUID, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
componentType := component.Type
|
||||||
|
if componentType != constants.DemoType {
|
||||||
|
logger.Error(ctx, "can not process real time data of component type not equal DemoType",
|
||||||
|
"component_uuid", componentUUID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var anchorName string
|
||||||
|
var compareValUpperLimit, compareValLowerLimit float64
|
||||||
|
var anchorRealTimeData []float64
|
||||||
|
var calculateFunc func(archorValue float64, args ...float64) float64
|
||||||
|
|
||||||
|
// 收集实时数据
|
||||||
|
for _, param := range realTimeData.Payload.Values {
|
||||||
|
anchorRealTimeData = append(anchorRealTimeData, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
anchorConfig := config.AnchorParamConfig{
|
||||||
|
AnchorParamBaseConfig: config.AnchorParamBaseConfig{
|
||||||
|
ComponentUUID: componentUUID,
|
||||||
|
AnchorName: anchorName,
|
||||||
|
CompareValUpperLimit: compareValUpperLimit,
|
||||||
|
CompareValLowerLimit: compareValLowerLimit,
|
||||||
|
AnchorRealTimeData: anchorRealTimeData,
|
||||||
|
},
|
||||||
|
CalculateFunc: calculateFunc,
|
||||||
|
CalculateParams: []float64{},
|
||||||
|
}
|
||||||
|
|
||||||
|
anchorChan, err := pool.GetAnchorParamChan(ctx, componentUUID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "get anchor param chan failed",
|
||||||
|
"component_uuid", componentUUID, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 使用select避免channel阻塞
|
||||||
|
select {
|
||||||
|
case anchorChan <- anchorConfig:
|
||||||
|
// 成功发送
|
||||||
|
case <-ctx.Done():
|
||||||
|
logger.Info(ctx, "context done while sending to anchor chan")
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
logger.Error(ctx, "timeout sending to anchor chan", "component_uuid", componentUUID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func processMessageBatch(ctx context.Context, messages []*kafka.Message) {
|
||||||
|
for _, msg := range messages {
|
||||||
|
realTimeData, err := parseKafkaMessage(msg.Value)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "parse kafka message failed", "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
processRealTimeData(ctx, realTimeData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
// Package realtimedata define real time data operation functions
|
|
||||||
package realtimedata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"modelRT/config"
|
|
||||||
"modelRT/constants"
|
|
||||||
"modelRT/diagram"
|
|
||||||
"modelRT/logger"
|
|
||||||
"modelRT/network"
|
|
||||||
"modelRT/pool"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RealTimeDataChan define channel of real time data receive
|
|
||||||
var RealTimeDataChan chan network.RealTimeDataReceiveRequest
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RealTimeDataChan = make(chan network.RealTimeDataReceiveRequest, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveChan define func of real time data receive and process
|
|
||||||
func ReceiveChan(ctx context.Context) {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
case realTimeData := <-RealTimeDataChan:
|
|
||||||
componentUUID := realTimeData.PayLoad.ComponentUUID
|
|
||||||
component, err := diagram.GetComponentMap(componentUUID)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(ctx, "query component info from diagram map by componet id failed", "component_uuid", componentUUID, "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
componentType := component.Type
|
|
||||||
if componentType != constants.DemoType {
|
|
||||||
logger.Error(ctx, "can not process real time data of component type not equal DemoType", "component_uuid", componentUUID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var anchorName string
|
|
||||||
var compareValUpperLimit, compareValLowerLimit float64
|
|
||||||
var anchorRealTimeData []float64
|
|
||||||
var calculateFunc func(archorValue float64, args ...float64) float64
|
|
||||||
|
|
||||||
// calculateFunc, params := config.SelectAnchorCalculateFuncAndParams(componentType, anchorName, componentData)
|
|
||||||
|
|
||||||
for _, param := range realTimeData.PayLoad.Values {
|
|
||||||
anchorRealTimeData = append(anchorRealTimeData, param.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
anchorConfig := config.AnchorParamConfig{
|
|
||||||
AnchorParamBaseConfig: config.AnchorParamBaseConfig{
|
|
||||||
ComponentUUID: componentUUID,
|
|
||||||
AnchorName: anchorName,
|
|
||||||
CompareValUpperLimit: compareValUpperLimit,
|
|
||||||
CompareValLowerLimit: compareValLowerLimit,
|
|
||||||
AnchorRealTimeData: anchorRealTimeData,
|
|
||||||
},
|
|
||||||
CalculateFunc: calculateFunc,
|
|
||||||
CalculateParams: []float64{},
|
|
||||||
}
|
|
||||||
anchorChan, err := pool.GetAnchorParamChan(ctx, componentUUID)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(ctx, "get anchor param chan failed", "component_uuid", componentUUID, "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
anchorChan <- anchorConfig
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,6 +10,6 @@ import (
|
||||||
// registerMonitorRoutes define func of register monitordata routes
|
// registerMonitorRoutes define func of register monitordata routes
|
||||||
func registerMonitorRoutes(rg *gin.RouterGroup) {
|
func registerMonitorRoutes(rg *gin.RouterGroup) {
|
||||||
g := rg.Group("/monitors/")
|
g := rg.Group("/monitors/")
|
||||||
g.POST("/data/subscriptions", handler.RealTimeSubHandler)
|
g.POST("data/subscriptions", handler.RealTimeSubHandler)
|
||||||
g.GET("/data/realtime/stream/:clientID", handler.PullRealTimeDataHandler)
|
g.GET("data/realtime/stream/:clientID", handler.PullRealTimeDataHandler)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue