fix: propagate request context through handlers

- pass c.Request.Context() to handler logs, DB calls, Redis wrappers,
and subscription operations
- avoid passing gin.Context into downstream model/database/diagram
layers
- keep async Redis backfill trace context without coupling it to request
cancellation
- add caller skip handling for facade logger output
This commit is contained in:
douxu 2026-07-08 10:37:06 +08:00
parent b53746efcd
commit f9824e2b24
22 changed files with 229 additions and 141 deletions

View File

@ -15,13 +15,14 @@ import (
// QueryAlertEventHandler define query alert event process API
func QueryAlertEventHandler(c *gin.Context) {
ctx := c.Request.Context()
var targetLevel constants.AlertLevel
alertManger := alert.GetAlertMangerInstance()
levelStr := c.Query("level")
level, err := strconv.Atoi(levelStr)
if err != nil {
logger.Error(c, "convert alert level string to int failed", "error", err)
logger.Error(ctx, "convert alert level string to int failed", "error", err)
resp := network.FailureResponse{
Code: -1,

View File

@ -19,15 +19,16 @@ import (
// ComponentAnchorReplaceHandler define component anchor point replace process API
func ComponentAnchorReplaceHandler(c *gin.Context) {
ctx := c.Request.Context()
var uuid, anchorName string
pgClient := database.GetPostgresDBClient()
cancelCtx, cancel := context.WithTimeout(c, 5*time.Second)
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
var request network.ComponetAnchorReplaceRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "unmarshal component anchor point replace info failed", "error", err)
logger.Error(ctx, "unmarshal component anchor point replace info failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -42,7 +43,7 @@ func ComponentAnchorReplaceHandler(c *gin.Context) {
var componentInfo orm.Component
result := pgClient.WithContext(cancelCtx).Model(&orm.Component{}).Where("global_uuid = ?", uuid).Find(&componentInfo)
if result.Error != nil {
logger.Error(c, "query component detail info failed", "error", result.Error)
logger.Error(ctx, "query component detail info failed", "error", result.Error)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -54,7 +55,7 @@ func ComponentAnchorReplaceHandler(c *gin.Context) {
if result.RowsAffected == 0 {
err := fmt.Errorf("query component detail info by uuid failed:%w", errcode.ErrQueryRowZero)
logger.Error(c, "query component detail info from table is empty", "table_name", "component")
logger.Error(ctx, "query component detail info from table is empty", "table_name", "component")
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -13,12 +13,13 @@ import (
// AttrDeleteHandler deletes a data attribute
func AttrDeleteHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.AttrDeleteRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -27,7 +28,7 @@ func AttrDeleteHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal attribute delete request", "error", err)
logger.Error(ctx, "failed to unmarshal attribute delete request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -35,9 +36,9 @@ func AttrDeleteHandler(c *gin.Context) {
return
}
rs := diagram.NewRedisString(c, request.AttrToken, clientToken, 10, true)
rs := diagram.NewRedisString(ctx, request.AttrToken, clientToken, 10, true)
if err := rs.GETDEL(request.AttrToken); err != nil {
logger.Error(c, "failed to delete attribute from Redis", "attr_token", request.AttrToken, "error", err)
logger.Error(ctx, "failed to delete attribute from Redis", "attr_token", request.AttrToken, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),

View File

@ -13,13 +13,14 @@ import (
// AttrGetHandler retrieves the value of a data attribute
func AttrGetHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.AttrGetRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -28,7 +29,7 @@ func AttrGetHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal attribute get request", "error", err)
logger.Error(ctx, "failed to unmarshal attribute get request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -37,12 +38,12 @@ func AttrGetHandler(c *gin.Context) {
}
pgClient := database.GetPostgresDBClient()
tx := pgClient.Begin()
tx := pgClient.WithContext(ctx).Begin()
attrModel, err := database.ParseAttrToken(c, tx, request.AttrToken, clientToken)
attrModel, err := database.ParseAttrToken(ctx, tx, request.AttrToken, clientToken)
if err != nil {
tx.Rollback()
logger.Error(c, "failed to parse attribute token", "attr_token", request.AttrToken, "error", err)
logger.Error(ctx, "failed to parse attribute token", "attr_token", request.AttrToken, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),

View File

@ -13,13 +13,14 @@ import (
// AttrSetHandler sets the value of a data attribute
func AttrSetHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.AttrSetRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -28,7 +29,7 @@ func AttrSetHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal attribute set request", "error", err)
logger.Error(ctx, "failed to unmarshal attribute set request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -37,9 +38,9 @@ func AttrSetHandler(c *gin.Context) {
}
// The logic for handling Redis operations directly from the handler
rs := diagram.NewRedisString(c, request.AttrToken, clientToken, 10, true)
rs := diagram.NewRedisString(ctx, request.AttrToken, clientToken, 10, true)
if err := rs.Set(request.AttrToken, request.AttrValue); err != nil {
logger.Error(c, "failed to set attribute value in Redis", "attr_token", request.AttrToken, "error", err)
logger.Error(ctx, "failed to set attribute value in Redis", "attr_token", request.AttrToken, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),

View File

@ -16,11 +16,12 @@ import (
// CircuitDiagramCreateHandler define circuit diagram create process API
func CircuitDiagramCreateHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
var request network.CircuitDiagramCreateRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "unmarshal circuit diagram create info failed", "error", err)
logger.Error(ctx, "unmarshal circuit diagram create info failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -32,7 +33,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
graph, err := diagram.GetGraphMap(request.PageID)
if err != nil {
logger.Error(c, "get topologic data from set by pageID failed", "error", err)
logger.Error(ctx, "get topologic data from set by pageID failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -60,7 +61,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
err = fmt.Errorf("convert uuid from string failed:%w:%w", err1, err2)
}
logger.Error(c, "format uuid from string failed", "error", err)
logger.Error(ctx, "format uuid from string failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -78,13 +79,13 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
}
// open transaction
tx := pgClient.Begin()
tx := pgClient.WithContext(ctx).Begin()
err = database.CreateTopologicIntoDB(c, tx, request.PageID, topologicCreateInfos)
err = database.CreateTopologicIntoDB(ctx, tx, request.PageID, topologicCreateInfos)
if err != nil {
tx.Rollback()
logger.Error(c, "create topologic info into DB failed", "topologic_info", topologicCreateInfos, "error", err)
logger.Error(ctx, "create topologic info into DB failed", "topologic_info", topologicCreateInfos, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -102,11 +103,11 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
}
for index, info := range request.ComponentInfos {
componentUUID, err := database.CreateComponentIntoDB(c, tx, info)
componentUUID, err := database.CreateComponentIntoDB(ctx, tx, info)
if err != nil {
tx.Rollback()
logger.Error(c, "insert component info into DB failed", "error", err)
logger.Error(ctx, "insert component info into DB failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -125,7 +126,7 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
// TODO 修复赋值问题
component, err := network.ConvertComponentCreateInfosToComponents(info)
if err != nil {
logger.Error(c, "convert component params info failed", "component_info", info, "error", err)
logger.Error(ctx, "convert component params info failed", "component_info", info, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -21,11 +21,12 @@ import (
// CircuitDiagramDeleteHandler define circuit diagram delete process API
func CircuitDiagramDeleteHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
var request network.CircuitDiagramDeleteRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "unmarshal circuit diagram del info failed", "error", err)
logger.Error(ctx, "unmarshal circuit diagram del info failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -37,7 +38,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
graph, err := diagram.GetGraphMap(request.PageID)
if err != nil {
logger.Error(c, "get topologic data from set by pageID failed", "error", err)
logger.Error(ctx, "get topologic data from set by pageID failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -65,7 +66,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
err = fmt.Errorf("convert uuid from string failed:%w:%w", err1, err2)
}
logger.Error(c, "format uuid from string failed", "error", err)
logger.Error(ctx, "format uuid from string failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -83,14 +84,14 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
}
// open transaction
tx := pgClient.Begin()
tx := pgClient.WithContext(ctx).Begin()
for _, topologicDelInfo := range topologicDelInfos {
err = database.DeleteTopologicIntoDB(c, tx, request.PageID, topologicDelInfo)
err = database.DeleteTopologicIntoDB(ctx, tx, request.PageID, topologicDelInfo)
if err != nil {
tx.Rollback()
logger.Error(c, "delete topologic info into DB failed", "topologic_info", topologicDelInfo, "error", err)
logger.Error(ctx, "delete topologic info into DB failed", "topologic_info", topologicDelInfo, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -107,7 +108,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
if err != nil {
tx.Rollback()
logger.Error(c, "delete topologic info failed", "topologic_info", topologicDelInfo, "error", err)
logger.Error(ctx, "delete topologic info failed", "topologic_info", topologicDelInfo, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -126,14 +127,14 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
}
for _, componentInfo := range request.ComponentInfos {
cancelCtx, cancel := context.WithTimeout(c, 5*time.Second)
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
globalUUID, err := uuid.FromString(componentInfo.UUID)
if err != nil {
tx.Rollback()
logger.Error(c, "format uuid from string failed", "error", err)
logger.Error(ctx, "format uuid from string failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -157,7 +158,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
err = fmt.Errorf("%w:please check uuid conditions", errcode.ErrDeleteRowZero)
}
logger.Error(c, "query component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err)
logger.Error(ctx, "query component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -179,7 +180,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
err = fmt.Errorf("%w:please check uuid conditions", errcode.ErrDeleteRowZero)
}
logger.Error(c, "delete component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err)
logger.Error(ctx, "delete component info into postgresDB failed", "component_global_uuid", componentInfo.UUID, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -24,11 +24,12 @@ import (
// @Failure 400 {object} network.FailureResponse "request process failed"
// @Router /model/diagram_load/{page_id} [get]
func CircuitDiagramLoadHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
pageID, err := strconv.ParseInt(c.Query("page_id"), 10, 64)
if err != nil {
logger.Error(c, "get pageID from url param failed", "error", err)
logger.Error(ctx, "get pageID from url param failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -43,7 +44,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
topologicInfo, err := diagram.GetGraphMap(pageID)
if err != nil {
logger.Error(c, "get topologic data from set by pageID failed", "error", err)
logger.Error(ctx, "get topologic data from set by pageID failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -62,9 +63,9 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
componentParamMap := make(map[string]any)
for _, VerticeLink := range topologicInfo.VerticeLinks {
for _, componentUUID := range VerticeLink {
component, err := database.QueryComponentByUUID(c, pgClient, componentUUID)
component, err := database.QueryComponentByUUID(ctx, pgClient, componentUUID)
if err != nil {
logger.Error(c, "get component id info from DB by uuid failed", "error", err)
logger.Error(ctx, "get component id info from DB by uuid failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -79,7 +80,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
componentParams, err := diagram.GetComponentMap(component.GlobalUUID.String())
if err != nil {
logger.Error(c, "get component data from set by uuid failed", "error", err)
logger.Error(ctx, "get component data from set by uuid failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -96,9 +97,9 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
}
rootVertexUUID := topologicInfo.RootVertex.String()
rootComponent, err := database.QueryComponentByUUID(c, pgClient, topologicInfo.RootVertex)
rootComponent, err := database.QueryComponentByUUID(ctx, pgClient, topologicInfo.RootVertex)
if err != nil {
logger.Error(c, "get component id info from DB by uuid failed", "error", err)
logger.Error(ctx, "get component id info from DB by uuid failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -113,7 +114,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
rootComponentParam, err := diagram.GetComponentMap(rootComponent.GlobalUUID.String())
if err != nil {
logger.Error(c, "get component data from set by uuid failed", "error", err)
logger.Error(ctx, "get component data from set by uuid failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -14,11 +14,12 @@ import (
// CircuitDiagramUpdateHandler define circuit diagram update process API
func CircuitDiagramUpdateHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
var request network.CircuitDiagramUpdateRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "unmarshal circuit diagram update info failed", "error", err)
logger.Error(ctx, "unmarshal circuit diagram update info failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -30,7 +31,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
graph, err := diagram.GetGraphMap(request.PageID)
if err != nil {
logger.Error(c, "get topologic data from set by pageID failed", "error", err)
logger.Error(ctx, "get topologic data from set by pageID failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -47,7 +48,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
for _, topologicLink := range request.TopologicLinks {
changeInfo, err := network.ParseUUID(topologicLink)
if err != nil {
logger.Error(c, "format uuid from string failed", "error", err)
logger.Error(ctx, "format uuid from string failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -63,14 +64,14 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
}
// open transaction
tx := pgClient.Begin()
tx := pgClient.WithContext(ctx).Begin()
for _, topologicChangeInfo := range topologicChangeInfos {
err = database.UpdateTopologicIntoDB(c, tx, request.PageID, topologicChangeInfo)
err = database.UpdateTopologicIntoDB(ctx, tx, request.PageID, topologicChangeInfo)
if err != nil {
tx.Rollback()
logger.Error(c, "update topologic info into DB failed", "topologic_info", topologicChangeInfo, "error", err)
logger.Error(ctx, "update topologic info into DB failed", "topologic_info", topologicChangeInfo, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -87,7 +88,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
if err != nil {
tx.Rollback()
logger.Error(c, "update topologic info failed", "topologic_info", topologicChangeInfo, "error", err)
logger.Error(ctx, "update topologic info failed", "topologic_info", topologicChangeInfo, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -102,9 +103,9 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
}
for index, componentInfo := range request.ComponentInfos {
componentUUID, err := database.UpdateComponentIntoDB(c, tx, componentInfo)
componentUUID, err := database.UpdateComponentIntoDB(ctx, tx, componentInfo)
if err != nil {
logger.Error(c, "udpate component info into DB failed", "error", err)
logger.Error(ctx, "udpate component info into DB failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -124,7 +125,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
// TODO 修复赋值问题
component, err := network.ConvertComponentUpdateInfosToComponents(info)
if err != nil {
logger.Error(c, "convert component params info failed", "component_info", info, "error", err)
logger.Error(ctx, "convert component params info failed", "component_info", info, "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -22,12 +22,13 @@ import (
// ComponentAttributeQueryHandler define circuit diagram component attribute value query process API
func ComponentAttributeQueryHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
tokens := c.Param("tokens")
if tokens == "" {
err := fmt.Errorf("tokens is missing from the path")
logger.Error(c, "query tokens from path failed", "error", err, "url", c.Request.RequestURI)
logger.Error(ctx, "query tokens from path failed", "error", err, "url", c.Request.RequestURI)
renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil)
return
}
@ -54,10 +55,10 @@ func ComponentAttributeQueryHandler(c *gin.Context) {
dbQueryMap := make(map[string][]cacheQueryItem)
var secondaryQueryCount int
for hSetKey, items := range cacheQueryMap {
hset := diagram.NewRedisHash(c, hSetKey, 5000, false)
hset := diagram.NewRedisHash(ctx, hSetKey, 5000, false)
cacheData, err := hset.HGetAll()
if err != nil {
logger.Warn(c, "redis hgetall failed", "key", hSetKey, "err", err)
logger.Warn(ctx, "redis hgetall failed", "key", hSetKey, "err", err)
}
for _, item := range items {
if val, ok := cacheData[item.attributeName]; ok {
@ -75,9 +76,9 @@ func ComponentAttributeQueryHandler(c *gin.Context) {
return
}
tx := pgClient.WithContext(c).Begin()
tx := pgClient.WithContext(ctx).Begin()
if tx.Error != nil {
logger.Error(c, "begin postgres transaction failed", "error", tx.Error)
logger.Error(ctx, "begin postgres transaction failed", "error", tx.Error)
fillRemainingErrors(queryResults, tokenSlice, errcode.ErrBeginTxFailed)
payload := genQueryRespPayload(queryResults, tokenSlice)
renderRespFailure(c, constants.RespCodeServerError, "begin postgres database transaction failed", payload)
@ -86,9 +87,9 @@ func ComponentAttributeQueryHandler(c *gin.Context) {
defer tx.Rollback()
allCompTags := slices.Collect(maps.Keys(dbQueryMap))
compModelMap, err := database.QueryComponentByCompTags(c, tx, allCompTags)
compModelMap, err := database.QueryComponentByCompTags(ctx, tx, allCompTags)
if err != nil {
logger.Error(c, "query component info from postgres database failed", "error", err)
logger.Error(ctx, "query component info from postgres database failed", "error", err)
fillRemainingErrors(queryResults, tokenSlice, errcode.ErrDBQueryFailed)
payload := genQueryRespPayload(queryResults, tokenSlice)
renderRespFailure(c, constants.RespCodeServerError, "query component meta failed", payload)
@ -116,7 +117,7 @@ func ComponentAttributeQueryHandler(c *gin.Context) {
tableNameMap, err := database.BatchGetProjectNames(tx, identifiers)
if err != nil {
logger.Error(c, "batch get table names from postgres database failed", "error", err)
logger.Error(ctx, "batch get table names from postgres database failed", "error", err)
fillRemainingErrors(queryResults, tokenSlice, errcode.ErrRetrieveFailed)
payload := genQueryRespPayload(queryResults, tokenSlice)
renderRespFailure(c, constants.RespCodeServerError, "batch get table names from postgres database failed", payload)
@ -151,10 +152,11 @@ func ComponentAttributeQueryHandler(c *gin.Context) {
}
if err := tx.Commit().Error; err != nil {
logger.Warn(c, "postgres transaction commit failed, but returning scanned data", "error", err)
logger.Warn(ctx, "postgres transaction commit failed, but returning scanned data", "error", err)
} else {
backfillCtx := context.WithoutCancel(ctx)
for hKey, items := range redisSyncMap {
go backfillRedis(c.Copy(), hKey, items)
go backfillRedis(backfillCtx, hKey, items)
}
}

View File

@ -18,10 +18,11 @@ import (
// ComponentAttributeUpdateHandler define circuit diagram component attribute value update process API
func ComponentAttributeUpdateHandler(c *gin.Context) {
ctx := c.Request.Context()
pgClient := database.GetPostgresDBClient()
var request network.ComponentAttributeUpdateInfo
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "unmarshal request params failed", "error", err)
logger.Error(ctx, "unmarshal request params failed", "error", err)
renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil)
return
}
@ -54,16 +55,16 @@ func ComponentAttributeUpdateHandler(c *gin.Context) {
}
// open transaction
tx := pgClient.WithContext(c).Begin()
tx := pgClient.WithContext(ctx).Begin()
if tx.Error != nil {
logger.Error(c, "begin postgres transaction failed", "error", tx.Error)
logger.Error(ctx, "begin postgres transaction failed", "error", tx.Error)
renderRespFailure(c, constants.RespCodeServerError, "begin postgres transaction failed", nil)
return
}
compInfo, err := database.QueryComponentByCompTag(c, tx, attributeComponentTag)
compInfo, err := database.QueryComponentByCompTag(ctx, tx, attributeComponentTag)
if err != nil {
logger.Error(c, "query component info by component tag failed", "error", err, "tag", attributeComponentTag)
logger.Error(ctx, "query component info by component tag failed", "error", err, "tag", attributeComponentTag)
for _, attribute := range request.AttributeConfigs {
if _, exists := updateResults[attribute.AttributeToken]; !exists {
@ -139,7 +140,7 @@ func ComponentAttributeUpdateHandler(c *gin.Context) {
}
for key, items := range redisUpdateMap {
hset := diagram.NewRedisHash(c, key, 5000, false)
hset := diagram.NewRedisHash(ctx, key, 5000, false)
fields := make(map[string]any, len(items))
for _, item := range items {
@ -147,7 +148,7 @@ func ComponentAttributeUpdateHandler(c *gin.Context) {
}
if err := hset.SetRedisHashByMap(fields); err != nil {
logger.Error(c, "batch sync redis failed", "hash_key", key, "error", err)
logger.Error(ctx, "batch sync redis failed", "hash_key", key, "error", err)
for _, item := range items {
if _, exists := updateResults[item.token]; exists {

View File

@ -41,11 +41,12 @@ var linkSetConfigs = map[int]linkSetConfig{
// DiagramNodeLinkHandler defines the diagram node link process api
func DiagramNodeLinkHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.DiagramNodeLinkRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -54,7 +55,7 @@ func DiagramNodeLinkHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal diagram node process request", "error", err)
logger.Error(ctx, "failed to unmarshal diagram node process request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -68,9 +69,9 @@ func DiagramNodeLinkHandler(c *gin.Context) {
nodeID := request.NodeID
nodeLevel := request.NodeLevel
action := request.Action
prevNodeInfo, currNodeInfo, err := database.QueryNodeInfoByID(c, pgClient, nodeID, nodeLevel)
prevNodeInfo, currNodeInfo, err := database.QueryNodeInfoByID(ctx, pgClient, nodeID, nodeLevel)
if err != nil {
logger.Error(c, "failed to query diagram node info by nodeID and level from postgres", "node_id", nodeID, "level", nodeLevel, "error", err)
logger.Error(ctx, "failed to query diagram node info by nodeID and level from postgres", "node_id", nodeID, "level", nodeLevel, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -84,8 +85,8 @@ func DiagramNodeLinkHandler(c *gin.Context) {
return
}
prevLinkSet, currLinkSet := generateLinkSet(c, nodeLevel, prevNodeInfo)
err = processLinkSetData(c, action, nodeLevel, prevLinkSet, currLinkSet, prevNodeInfo, currNodeInfo)
prevLinkSet, currLinkSet := generateLinkSet(ctx, nodeLevel, prevNodeInfo)
err = processLinkSetData(ctx, action, nodeLevel, prevLinkSet, currLinkSet, prevNodeInfo, currNodeInfo)
if err != nil {
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -99,7 +100,7 @@ func DiagramNodeLinkHandler(c *gin.Context) {
return
}
logger.Info(c, "process diagram node link success", "node_id", nodeID, "level", nodeLevel, "action", request.Action)
logger.Info(ctx, "process diagram node link success", "node_id", nodeID, "level", nodeLevel, "action", request.Action)
c.JSON(http.StatusOK, network.SuccessResponse{
Code: http.StatusOK,

View File

@ -16,11 +16,12 @@ import (
// QueryHistoryDataHandler define query history data process API
func QueryHistoryDataHandler(c *gin.Context) {
ctx := c.Request.Context()
token := c.Query("token")
beginStr := c.Query("begin")
begin, err := strconv.Atoi(beginStr)
if err != nil {
logger.Error(c, "convert begin param from string to int failed", "error", err)
logger.Error(ctx, "convert begin param from string to int failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,
@ -31,7 +32,7 @@ func QueryHistoryDataHandler(c *gin.Context) {
endStr := c.Query("end")
end, err := strconv.Atoi(endStr)
if err != nil {
logger.Error(c, "convert end param from string to int failed", "error", err)
logger.Error(ctx, "convert end param from string to int failed", "error", err)
resp := network.FailureResponse{
Code: http.StatusBadRequest,

View File

@ -15,13 +15,14 @@ import (
// MeasurementGetHandler define measurement query API
func MeasurementGetHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.MeasurementGetRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -30,7 +31,7 @@ func MeasurementGetHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal measurement get request", "error", err)
logger.Error(ctx, "failed to unmarshal measurement get request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -38,10 +39,10 @@ func MeasurementGetHandler(c *gin.Context) {
return
}
zset := diagram.NewRedisZSet(c, request.MeasurementToken, 0, false)
zset := diagram.NewRedisZSet(ctx, request.MeasurementToken, 0, false)
points, err := zset.ZRANGE(request.MeasurementToken, 0, -1)
if err != nil {
logger.Error(c, "failed to get measurement data from redis", "measurement_token", request.MeasurementToken, "error", err)
logger.Error(ctx, "failed to get measurement data from redis", "measurement_token", request.MeasurementToken, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusInternalServerError,
Msg: err.Error(),
@ -54,9 +55,9 @@ func MeasurementGetHandler(c *gin.Context) {
}
pgClient := database.GetPostgresDBClient()
measurementInfo, err := database.QueryMeasurementByID(c, pgClient, request.MeasurementID)
measurementInfo, err := database.QueryMeasurementByID(ctx, pgClient, request.MeasurementID)
if err != nil {
logger.Error(c, "failed to query measurement by id", "measurement_id", request.MeasurementID, "error", err)
logger.Error(ctx, "failed to query measurement by id", "measurement_id", request.MeasurementID, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),

View File

@ -2,11 +2,12 @@
package handler
import (
"net/http"
"modelRT/constants"
"modelRT/logger"
"modelRT/model"
"modelRT/network"
"net/http"
"github.com/gin-gonic/gin"
)
@ -43,18 +44,18 @@ import (
//
// @Router /measurement/recommend [get]
func MeasurementRecommendHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.MeasurementRecommendRequest
if err := c.ShouldBindQuery(&request); err != nil {
logger.Error(c, "failed to bind measurement recommend request", "error", err)
logger.Error(ctx, "failed to bind measurement recommend request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
})
return
}
recommendResults := model.RedisSearchRecommend(c, request.Input)
recommendResults := model.RedisSearchRecommend(ctx, request.Input)
payload := network.MeasurementRecommendPayload{
Input: request.Input,
RecommendedList: make([]string, 0),
@ -65,7 +66,7 @@ func MeasurementRecommendHandler(c *gin.Context) {
for _, recommendResult := range orderedResults {
if recommendResult.Err != nil {
err := recommendResult.Err
logger.Error(c, "failed to get recommend data from redis", "input", request.Input, "error", err)
logger.Error(ctx, "failed to get recommend data from redis", "input", request.Input, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusInternalServerError,
Msg: err.Error(),

View File

@ -18,11 +18,12 @@ import (
// MeasurementLinkHandler defines the measurement link process api
func MeasurementLinkHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.MeasurementLinkRequest
clientToken := c.GetString("client_token")
if clientToken == "" {
err := common.ErrGetClientToken
logger.Error(c, "failed to get client token from context", "error", err)
logger.Error(ctx, "failed to get client token from context", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -31,7 +32,7 @@ func MeasurementLinkHandler(c *gin.Context) {
}
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal measurement process request", "error", err)
logger.Error(ctx, "failed to unmarshal measurement process request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -44,9 +45,9 @@ func MeasurementLinkHandler(c *gin.Context) {
pgClient := database.GetPostgresDBClient()
measurementID := request.MeasurementID
action := request.Action
measurementInfo, err := database.QueryMeasurementByID(c, pgClient, measurementID)
measurementInfo, err := database.QueryMeasurementByID(ctx, pgClient, measurementID)
if err != nil {
logger.Error(c, "failed to query measurement info by measurement id from postgres", "meauserement_id", measurementID, "error", err)
logger.Error(ctx, "failed to query measurement info by measurement id from postgres", "meauserement_id", measurementID, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -59,9 +60,9 @@ func MeasurementLinkHandler(c *gin.Context) {
return
}
componentInfo, err := database.QueryComponentByUUID(c, pgClient, measurementInfo.ComponentUUID)
componentInfo, err := database.QueryComponentByUUID(ctx, pgClient, measurementInfo.ComponentUUID)
if err != nil {
logger.Error(c, "failed to query component info by component uuid from postgres", "component_uuid", measurementInfo.ComponentUUID, "error", err)
logger.Error(ctx, "failed to query component info by component uuid from postgres", "component_uuid", measurementInfo.ComponentUUID, "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
@ -74,9 +75,9 @@ func MeasurementLinkHandler(c *gin.Context) {
return
}
allMeasSet := diagram.NewRedisSet(c, constants.RedisAllMeasTagSetKey, 0, false)
allMeasSet := diagram.NewRedisSet(ctx, constants.RedisAllMeasTagSetKey, 0, false)
compMeasLinkKey := fmt.Sprintf(constants.RedisSpecCompTagMeasSetKey, componentInfo.Tag)
compMeasLinkSet := diagram.NewRedisSet(c, compMeasLinkKey, 0, false)
compMeasLinkSet := diagram.NewRedisSet(ctx, compMeasLinkKey, 0, false)
switch action {
case constants.SearchLinkAddAction:
@ -84,18 +85,18 @@ func MeasurementLinkHandler(c *gin.Context) {
err2 := compMeasLinkSet.SADD(measurementInfo.Tag)
err = processActionError(err1, err2, action)
if err != nil {
logger.Error(c, "add measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err)
logger.Error(ctx, "add measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err)
}
case constants.SearchLinkDelAction:
err1 := allMeasSet.SREM(measurementInfo.Tag)
err2 := compMeasLinkSet.SREM(measurementInfo.Tag)
err = processActionError(err1, err2, action)
if err != nil {
logger.Error(c, "del measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err)
logger.Error(ctx, "del measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err)
}
default:
err = common.ErrUnsupportedLinkAction
logger.Error(c, "unsupport measurement link process action", "measurement_id", measurementID, "action", action, "error", err)
logger.Error(ctx, "unsupport measurement link process action", "measurement_id", measurementID, "action", action, "error", err)
}
if err != nil {
@ -110,7 +111,7 @@ func MeasurementLinkHandler(c *gin.Context) {
return
}
logger.Info(c, "process measurement link success", "measurement_id", measurementID, "action", request.Action)
logger.Info(ctx, "process measurement link success", "measurement_id", measurementID, "action", request.Action)
c.JSON(http.StatusOK, network.SuccessResponse{
Code: http.StatusOK,

View File

@ -35,27 +35,28 @@ var pullUpgrader = websocket.Upgrader{
// @Tags RealTime Component Websocket
// @Router /monitors/data/realtime/stream/:clientID [get]
func PullRealTimeDataHandler(c *gin.Context) {
requestCtx := c.Request.Context()
clientID := c.Param("clientID")
if clientID == "" {
err := fmt.Errorf("clientID is missing from the path")
logger.Error(c, "query clientID from path failed", "error", err, "url", c.Request.RequestURI)
logger.Error(requestCtx, "query clientID from path failed", "error", err, "url", c.Request.RequestURI)
renderWSRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil)
return
}
conn, err := pullUpgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
logger.Error(c, "upgrade http protocol to websocket protocol failed", "error", err)
logger.Error(requestCtx, "upgrade http protocol to websocket protocol failed", "error", err)
renderWSRespFailure(c, constants.RespCodeServerError, err.Error(), nil)
return
}
defer conn.Close()
ctx, cancel := context.WithCancel(c.Request.Context())
ctx, cancel := context.WithCancel(requestCtx)
defer cancel()
conn.SetCloseHandler(func(code int, text string) error {
logger.Info(c.Request.Context(), "websocket processor shutdown trigger",
logger.Info(requestCtx, "websocket processor shutdown trigger",
"clientID", clientID, "code", code, "reason", text)
// call cancel to notify other goroutines to stop working

View File

@ -60,10 +60,11 @@ var wsUpgrader = websocket.Upgrader{
//
// @Router /data/realtime [get]
func QueryRealTimeDataHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.RealTimeQueryRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal real time query request", "error", err)
logger.Error(ctx, "failed to unmarshal real time query request", "error", err)
c.JSON(http.StatusOK, network.FailureResponse{
Code: http.StatusBadRequest,
Msg: err.Error(),
@ -73,7 +74,7 @@ func QueryRealTimeDataHandler(c *gin.Context) {
conn, err := wsUpgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
logger.Error(c, "upgrade http protocol to websocket protocal failed", "error", err)
logger.Error(ctx, "upgrade http protocol to websocket protocal failed", "error", err)
return
}
defer conn.Close()
@ -87,29 +88,29 @@ func QueryRealTimeDataHandler(c *gin.Context) {
case data := <-transportChannel:
respByte, err := jsoniter.Marshal(data)
if err != nil {
logger.Error(c, "marshal real time data to bytes failed", "error", err)
logger.Error(ctx, "marshal real time data to bytes failed", "error", err)
continue
}
err = conn.WriteMessage(websocket.TextMessage, respByte)
if err != nil {
logger.Error(c, "write message to websocket connection failed", "error", err)
logger.Error(ctx, "write message to websocket connection failed", "error", err)
continue
}
case <-closeChannel:
logger.Info(c, "data receiving goroutine has been closed")
logger.Info(ctx, "data receiving goroutine has been closed")
// TODO 优化时间控制
deadline := time.Now().Add(5 * time.Second)
err := conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "the session ended normally"), deadline)
if err != nil {
logger.Error(c, "sending close control message failed", "error", err)
logger.Error(ctx, "sending close control message failed", "error", err)
}
// gracefully close session processing
err = conn.Close()
if err != nil {
logger.Error(c, "websocket conn closed failed", "error", err)
logger.Error(ctx, "websocket conn closed failed", "error", err)
}
logger.Info(c, "websocket connection closed successfully.")
logger.Info(ctx, "websocket connection closed successfully.")
}
}
}

View File

@ -17,9 +17,10 @@ var upgrader = websocket.Upgrader{
// RealTimeDataReceivehandler define real time data receive and process API
func RealTimeDataReceivehandler(c *gin.Context) {
ctx := c.Request.Context()
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
logger.Error(c, "upgrade http protocol to websocket protocal failed", "error", err)
logger.Error(ctx, "upgrade http protocol to websocket protocal failed", "error", err)
return
}
defer conn.Close()
@ -27,17 +28,17 @@ func RealTimeDataReceivehandler(c *gin.Context) {
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
logger.Error(c, "read message from websocket connection failed", "error", err)
logger.Error(ctx, "read message from websocket connection failed", "error", err)
respByte := processResponse(-1, "read message from websocket connection failed", nil)
if len(respByte) == 0 {
logger.Error(c, "process message from byte failed", "error", err)
logger.Error(ctx, "process message from byte failed", "error", err)
continue
}
err = conn.WriteMessage(messageType, respByte)
if err != nil {
logger.Error(c, "write message to websocket connection failed", "error", err)
logger.Error(ctx, "write message to websocket connection failed", "error", err)
continue
}
continue
@ -46,17 +47,17 @@ func RealTimeDataReceivehandler(c *gin.Context) {
var request network.RealTimeDataReceiveRequest
err = jsoniter.Unmarshal([]byte(p), &request)
if err != nil {
logger.Error(c, "unmarshal message from byte failed", "error", err)
logger.Error(ctx, "unmarshal message from byte failed", "error", err)
respByte := processResponse(-1, "unmarshal message from byte failed", nil)
if len(respByte) == 0 {
logger.Error(c, "process message from byte failed", "error", err)
logger.Error(ctx, "process message from byte failed", "error", err)
continue
}
err = conn.WriteMessage(messageType, respByte)
if err != nil {
logger.Error(c, "write message to websocket connection failed", "error", err)
logger.Error(ctx, "write message to websocket connection failed", "error", err)
continue
}
continue
@ -70,13 +71,13 @@ func RealTimeDataReceivehandler(c *gin.Context) {
}
respByte := processResponse(0, "success", payload)
if len(respByte) == 0 {
logger.Error(c, "process message from byte failed", "error", err)
logger.Error(ctx, "process message from byte failed", "error", err)
continue
}
err = conn.WriteMessage(messageType, respByte)
if err != nil {
logger.Error(c, "write message to websocket connection failed", "error", err)
logger.Error(ctx, "write message to websocket connection failed", "error", err)
continue
}
}

View File

@ -77,12 +77,13 @@ func init() {
//
// @Router /monitors/data/subscriptions [post]
func RealTimeSubHandler(c *gin.Context) {
ctx := c.Request.Context()
var request network.RealTimeSubRequest
var subAction string
var clientID string
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error(c, "failed to unmarshal real time query request", "error", err)
logger.Error(ctx, "failed to unmarshal real time query request", "error", err)
renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil)
return
}
@ -91,7 +92,7 @@ func RealTimeSubHandler(c *gin.Context) {
subAction = request.Action
id, err := uuid.NewV4()
if err != nil {
logger.Error(c, "failed to generate client id", "error", err)
logger.Error(ctx, "failed to generate client id", "error", err)
renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil)
return
}
@ -114,9 +115,9 @@ func RealTimeSubHandler(c *gin.Context) {
switch subAction {
case constants.SubStartAction:
results, err := globalSubState.CreateConfig(c, tx, clientID, request.Measurements)
results, err := globalSubState.CreateConfig(ctx, tx, clientID, request.Measurements)
if err != nil {
logger.Error(c, "create real time data subscription config failed", "error", err)
logger.Error(ctx, "create real time data subscription config failed", "error", err)
renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{
ClientID: clientID,
TargetResults: results,
@ -130,9 +131,9 @@ func RealTimeSubHandler(c *gin.Context) {
})
return
case constants.SubStopAction:
results, err := globalSubState.RemoveTargets(c, clientID, request.Measurements)
results, err := globalSubState.RemoveTargets(ctx, clientID, request.Measurements)
if err != nil {
logger.Error(c, "remove target to real time data subscription config failed", "error", err)
logger.Error(ctx, "remove target to real time data subscription config failed", "error", err)
renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{
ClientID: clientID,
TargetResults: results,
@ -146,9 +147,9 @@ func RealTimeSubHandler(c *gin.Context) {
})
return
case constants.SubAppendAction:
results, err := globalSubState.AppendTargets(c, tx, clientID, request.Measurements)
results, err := globalSubState.AppendTargets(ctx, tx, clientID, request.Measurements)
if err != nil {
logger.Error(c, "append target to real time data subscription config failed", "error", err)
logger.Error(ctx, "append target to real time data subscription config failed", "error", err)
renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{
ClientID: clientID,
TargetResults: results,
@ -162,9 +163,9 @@ func RealTimeSubHandler(c *gin.Context) {
})
return
case constants.SubUpdateAction:
results, err := globalSubState.UpdateTargets(c, tx, clientID, request.Measurements)
results, err := globalSubState.UpdateTargets(ctx, tx, clientID, request.Measurements)
if err != nil {
logger.Error(c, "update target to real time data subscription config failed", "error", err)
logger.Error(ctx, "update target to real time data subscription config failed", "error", err)
renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{
ClientID: clientID,
TargetResults: results,
@ -179,7 +180,7 @@ func RealTimeSubHandler(c *gin.Context) {
return
default:
err := fmt.Errorf("%w: request action is %s", common.ErrUnsupportedSubAction, request.Action)
logger.Error(c, "unsupported action of real time data subscription request", "error", err)
logger.Error(ctx, "unsupported action of real time data subscription request", "error", err)
requestTargetsCount := processRealTimeRequestCount(request.Measurements)
results := processRealTimeRequestTargets(request.Measurements, requestTargetsCount, constants.CodeUnsupportSubOperation, err)
renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), network.RealTimeSubPayload{

View File

@ -18,6 +18,8 @@ type facade struct {
_logger *zap.Logger
}
const facadeCallerSkip = 2
// Debug define facade func of debug level log
func Debug(ctx context.Context, msg string, kv ...any) {
logFacade().log(ctx, zapcore.DebugLevel, msg, kv...)
@ -39,12 +41,16 @@ func Error(ctx context.Context, msg string, kv ...any) {
}
func (f *facade) log(ctx context.Context, lvl zapcore.Level, msg string, kv ...any) {
f.logSkip(ctx, lvl, 0, msg, kv...)
f.logSkip(ctx, lvl, 1, msg, kv...)
}
func (f *facade) logSkip(ctx context.Context, lvl zapcore.Level, extraSkip int, msg string, kv ...any) {
fields := makeLogFieldsSkip(ctx, extraSkip, kv...)
ce := f._logger.Check(lvl, msg)
logger := f._logger
if extraSkip > 0 {
logger = logger.WithOptions(zap.AddCallerSkip(extraSkip))
}
ce := logger.Check(lvl, msg)
ce.Write(fields...)
}
@ -66,7 +72,7 @@ func InfoSkip(ctx context.Context, extraSkip int, msg string, kv ...any) {
func logFacade() *facade {
fOnce.Do(func() {
f = &facade{
_logger: GetLoggerInstance(),
_logger: GetLoggerInstance().WithOptions(zap.AddCallerSkip(facadeCallerSkip)),
}
})
return f

View File

@ -1,6 +1,11 @@
package model
import "testing"
import (
"fmt"
"testing"
"modelRT/constants"
)
func TestFuzzyRecommendOffsetUsesFullMatchedInput(t *testing.T) {
tests := []struct {
@ -38,3 +43,59 @@ func TestFuzzyRecommendOffsetUsesFullMatchedInput(t *testing.T) {
})
}
}
func TestFallbackSpecificSetKey(t *testing.T) {
tests := []struct {
name string
hierarchy constants.RecommendHierarchyType
inputSlice []string
want string
wantOK bool
}{
{
name: "zone fallback uses grid specific set",
hierarchy: constants.ZoneRecommendHierarchyType,
inputSlice: []string{"grid000", "z"},
want: fmt.Sprintf(constants.RedisSpecGridZoneSetKey, "grid000"),
wantOK: true,
},
{
name: "component tag fallback uses previous nspath token",
hierarchy: constants.CompTagRecommendHierarchyType,
inputSlice: []string{"grid000", "I"},
want: fmt.Sprintf(constants.RedisSpecCompNSPathCompTagSetKey, "grid000"),
wantOK: true,
},
{
name: "measurement fallback skips config token and uses component tag",
hierarchy: constants.MeasTagRecommendHierarchyType,
inputSlice: []string{"nspath", "comp_tag", "config", "m"},
want: fmt.Sprintf(constants.RedisSpecCompTagMeasSetKey, "comp_tag"),
wantOK: true,
},
{
name: "config fallback has no parent specific set",
hierarchy: constants.ConfigRecommendHierarchyType,
inputSlice: []string{"nspath", "comp_tag", ""},
wantOK: false,
},
{
name: "missing previous token",
hierarchy: constants.ZoneRecommendHierarchyType,
inputSlice: []string{"z"},
wantOK: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, ok := fallbackSpecificSetKey(tt.hierarchy, tt.inputSlice)
if ok != tt.wantOK {
t.Fatalf("expected ok %t, got %t", tt.wantOK, ok)
}
if got != tt.want {
t.Fatalf("expected key %q, got %q", tt.want, got)
}
})
}
}