LingxinMeng 1 anno fa
parent
commit
57ff6f2910
3 ha cambiato i file con 45 aggiunte e 14 eliminazioni
  1. 25 12
      amd64/score_server/handler/h_exam.go
  2. 10 2
      common/util/u_map.go
  3. 10 0
      common/util/u_time.go

+ 25 - 12
amd64/score_server/handler/h_exam.go

@@ -25,7 +25,7 @@ import (
 var (
 	defaultTime            = time.Date(2006, time.January, 2, 15, 4, 5, 0, time.Local)
 	cacheMutex             sync.Mutex
-	cacheTeamName          = make(map[string]time.Time)
+	cacheTeamName          sync.Map            // = make(map[string]time.Time)
 	heartBeatTimeThreshold = 5 * time.Second   // 心跳时间
 	InitialPositionX       = 565266.0482367771 // todo 需要比赛确认起点
 	InitialPositionY       = 4329773.48728322  // todo 需要比赛确认起点
@@ -50,7 +50,7 @@ func Tick(c *gin.Context) {
 	var positionY float64
 	numStr := param.PositionY
 	_, _ = fmt.Sscanf(numStr, "%e", &positionY)
-	if !util.ContainsKey(cacheTeamName, teamName) && math.Abs(positionX-InitialPositionX) < 5.00 && math.Abs(positionY-InitialPositionY) < 5.00 { // (在起点开始)
+	if !util.ContainsKey(&cacheTeamName, teamName) && math.Abs(positionX-InitialPositionX) < 5.00 && math.Abs(positionY-InitialPositionY) < 5.00 { // (在起点开始)
 		sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-insert-begin_time-and-topic-and-equipment_no-by-team_name.sql"])
 
 		stage := ""
@@ -62,7 +62,8 @@ func Tick(c *gin.Context) {
 			stage = "决赛"
 		}
 		competitionBegin := time.Now()
-		cacheTeamName[teamName] = competitionBegin
+		//cacheTeamName[teamName] = competitionBegin
+		cacheTeamName.Store(teamName, competitionBegin)
 		c_log.GlobalLogger.Infof("当前比赛阶段为 %v ,队伍 %v 在起始点范围内第一次启动,保存新一条比赛记录的开始时间 %v", stage, teamName, competitionBegin)
 		if err := c_db.DoTx(sqlTemplate, []any{param.TeamName, stage, competitionBegin, param.EquipmentNo}); err != nil {
 			c_log.GlobalLogger.Error("保存比赛开始时间报错:", err)
@@ -73,7 +74,7 @@ func Tick(c *gin.Context) {
 			Code: 200,
 			Msg:  "队伍 " + teamName + " 的考试开始。",
 		})
-	} else if !util.ContainsKey(cacheTeamName, teamName) && (math.Abs(positionX-InitialPositionX) > 5.00 || math.Abs(positionY-InitialPositionY) > 5.00) { // 不在起点(开始)
+	} else if !util.ContainsKey(&cacheTeamName, teamName) && (math.Abs(positionX-InitialPositionX) > 5.00 || math.Abs(positionY-InitialPositionY) > 5.00) { // 不在起点(开始)
 		// 车辆不是在起点启动的自动驾驶模式
 		var result []webServerEntity.ExamPo
 		{
@@ -89,7 +90,8 @@ func Tick(c *gin.Context) {
 			if len(result) == 1 {
 				c_log.GlobalLogger.Info("上一条数据记录为:", result[0])
 				// 添加队伍名到缓存中
-				cacheTeamName[teamName] = time.Now()
+				cacheTeamName.Store(teamName, time.Now())
+				//cacheTeamName[teamName] = time.Now()
 			} else {
 				c_log.GlobalLogger.Errorf("队伍 %v 的考试车辆未在起点开启自动驾驶模式,且今日无考试记录,错误启动自动驾驶模式。", param.TeamName)
 				c.JSON(http.StatusOK, commonEntity.Response{
@@ -113,8 +115,9 @@ func Tick(c *gin.Context) {
 			Code: 200,
 			Msg:  "队伍 " + teamName + " 的考试在中途中断后重新开始。",
 		})
-	} else if util.ContainsKey(cacheTeamName, teamName) { // 进行中
-		cacheTeamName[teamName] = time.Now()
+	} else if util.ContainsKey(&cacheTeamName, teamName) { // 进行中
+		cacheTeamName.Store(teamName, time.Now())
+		//cacheTeamName[teamName] = time.Now()
 		c_log.GlobalLogger.Errorf("接收到心跳信息,队伍名字为 %s,x坐标为  %.f,y坐标为 %.f ", teamName, positionX, positionY)
 		c.JSON(http.StatusOK, commonEntity.Response{
 			Code: 200,
@@ -139,15 +142,25 @@ func ExamEndTicker() {
 			cacheMutex.Lock()
 			{
 				var keysToDelete []string
-				for teamName, heartBeatTime := range cacheTeamName {
+				cacheTeamName.Range(func(teamName, heartBeatTimeAny interface{}) bool {
+					heartBeatTime, _ := util.AnyToTime(heartBeatTimeAny)
 					if time.Since(heartBeatTime) > heartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
 						c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
-
-						keysToDelete = append(keysToDelete, teamName)
+						keysToDelete = append(keysToDelete, fmt.Sprintf("%v", teamName))
 					}
-				}
+					return true // 如果要终止遍历,返回 false
+				})
+
+				//for teamName, heartBeatTime := range cacheTeamName {
+				//	if time.Since(heartBeatTime) > heartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
+				//		c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
+				//
+				//		keysToDelete = append(keysToDelete, teamName)
+				//	}
+				//}
 				for _, teamName := range keysToDelete { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
-					delete(cacheTeamName, teamName)
+					cacheTeamName.Delete(teamName)
+					//delete(cacheTeamName, teamName)
 					// 1 查询指定队伍的开始时间最新的考试是否有结束时间,如果有则不在处理,如果没有则更新
 					var result []webServerEntity.ExamPo
 					selectSql, err := util.ReadFile(c_db.SqlFilesMap["exam-select-latest-by-team_name.sql"])

+ 10 - 2
common/util/u_map.go

@@ -1,12 +1,20 @@
 package util
 
-import "time"
+import (
+	"sync"
+	"time"
+)
 
 // 函数名为 ContainsKey,参数为一个 map 和一个 key
-func ContainsKey(m map[string]time.Time, key string) bool {
+func ContainsKey2(m map[string]time.Time, key string) bool {
 	// 通过 map[key] 来访问 map 中的值
 	// 如果 map[key] 返回的值存在,则表示该 key 存在于 map 中,返回 true
 	// 如果 map[key] 返回的值不存在,则表示该 key 不存在于 map 中,返回 false
 	_, exists := m[key]
 	return exists
 }
+
+func ContainsKey(m *sync.Map, key string) bool {
+	_, found := m.Load(key)
+	return found
+}

+ 10 - 0
common/util/u_time.go

@@ -1,6 +1,7 @@
 package util
 
 import (
+	"fmt"
 	"strconv"
 	"strings"
 	"time"
@@ -64,3 +65,12 @@ func GetTimeString(sourceTime time.Time) string {
 	}
 	return sourceTime.Format("2006-01-02 15:04:05")
 }
+
+func AnyToTime(value any) (time.Time, error) {
+	switch v := value.(type) {
+	case time.Time:
+		return v, nil
+	default:
+		return time.Time{}, fmt.Errorf("unsupported type: %T", value)
+	}
+}