From d8668afa463fe64e0528040aaf6438c5205fba52 Mon Sep 17 00:00:00 2001 From: douxu Date: Wed, 8 Jul 2026 14:41:13 +0800 Subject: [PATCH] refactor: simplify redis recommendation concurrency - replace fan-in channel recommendation searches with errgroup-based execution - return SearchResult directly from Redis recommendation helper functions - fallback leading-dot recommendation input to initial token suggestions - remove unused recommendLenType parameter from fuzzy member set validation - clean up small model selection and naming issues --- handler/async_task_create_handler.go | 4 + model/attribute_model.go | 4 +- model/model_select.go | 8 +- model/redis_recommend.go | 339 ++++++++++++--------------- util/time.go | 4 +- 5 files changed, 157 insertions(+), 202 deletions(-) diff --git a/handler/async_task_create_handler.go b/handler/async_task_create_handler.go index d1ff912..6da67c5 100644 --- a/handler/async_task_create_handler.go +++ b/handler/async_task_create_handler.go @@ -2,6 +2,8 @@ package handler import ( + "fmt" + "modelRT/constants" "modelRT/database" "modelRT/logger" @@ -152,6 +154,8 @@ func validateBatchImportParams(params map[string]any) bool { func validateTestTaskParams(params map[string]any) bool { // Test task has optional parameters, all are valid // sleep_duration defaults to 60 seconds if not provided + // TODO Add more validation logic for test task parameters if needed + fmt.Println(params) return true } diff --git a/model/attribute_model.go b/model/attribute_model.go index 601d156..6654dae 100644 --- a/model/attribute_model.go +++ b/model/attribute_model.go @@ -90,6 +90,6 @@ func (s *ShortAttrInfo) IsLocal() bool { } // GetAttrValue define return the attribute value -func (l *ShortAttrInfo) GetAttrValue() any { - return l.AttrValue +func (s *ShortAttrInfo) GetAttrValue() any { + return s.AttrValue } diff --git a/model/model_select.go b/model/model_select.go index 042a867..601eeba 100644 --- a/model/model_select.go +++ b/model/model_select.go @@ -1,3 +1,4 @@ +// Package model define model struct of model runtime service package model import ( @@ -7,11 +8,12 @@ import ( // SelectModelByType define select the data structure for parsing based on the input model type func SelectModelByType(modelType int) BasicModelInterface { - if modelType == constants.BusbarType { + switch modelType { + case constants.BusbarType: return &orm.BusbarSection{} - } else if modelType == constants.AsyncMotorType { + case constants.AsyncMotorType: return &orm.AsyncMotor{} - } else if modelType == constants.DemoType { + case constants.DemoType: return &orm.Demo{} } return nil diff --git a/model/redis_recommend.go b/model/redis_recommend.go index fa0db57..5249872 100644 --- a/model/redis_recommend.go +++ b/model/redis_recommend.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "strings" + "sync" "modelRT/constants" "modelRT/diagram" @@ -16,6 +17,7 @@ import ( "github.com/RediSearch/redisearch-go/v2/redisearch" redigo "github.com/gomodule/redigo/redis" "github.com/redis/go-redis/v9" + "golang.org/x/sync/errgroup" ) // SearchResult define struct to store redis query recommend search result @@ -36,12 +38,44 @@ func InitAutocompleterWithPool(pool *redigo.Pool) { ac = redisearch.NewAutocompleterFromPool(pool, constants.RedisSearchDictName) } +type recommendSearchJob func() SearchResult + +func runRecommendSearches(ctx context.Context, logMsg string, filterCompNSPath bool, jobs ...recommendSearchJob) map[string]SearchResult { + results := make(map[string]SearchResult) + var mu sync.Mutex + var group errgroup.Group + + for _, job := range jobs { + job := job + group.Go(func() error { + result := job() + if result.Err != nil { + return fmt.Errorf("%s: %w", result.RecommendType, result.Err) + } + + if filterCompNSPath && result.RecommendType == constants.CompNSPathRecommendHierarchyType { + result.QueryDatas = filterLocalNSPathResults(result.QueryDatas) + } + + mu.Lock() + results[result.RecommendType.String()] = result + mu.Unlock() + return nil + }) + } + + if err := group.Wait(); err != nil { + logger.Error(ctx, logMsg, "error", err) + } + return results +} + // levelOneRedisSearch 处理第一段输入的搜索, 例如 grid 或本地 nspath。 -func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, searchInput string, searchRedisKey string, fanInChan chan SearchResult) { +func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, searchInput string, searchRedisKey string) (result SearchResult) { defer func() { if r := recover(); r != nil { logger.Error(ctx, "searchFunc panicked", "panic", r) - fanInChan <- SearchResult{ + result = SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, @@ -54,64 +88,59 @@ func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy const if err != nil { logger.Error(ctx, "redis membership check failed", "key", searchRedisKey, "member", searchInput, "op", "SIsMember", "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } // the input key is the complete hierarchical value if exists { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: []string{"."}, IsFuzzy: false, Err: nil, } - return } // process fuzzy search result recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, "", hierarchy, recommendLenType) if err != nil { logger.Error(ctx, fmt.Sprintf("fuzzy search failed for %s hierarchical", util.GetLevelStrByRdsKey(searchRedisKey)), "search_input", searchInput, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } if len(recommends) > 0 { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: recommends, IsFuzzy: true, Offset: offset, Err: nil, } - return } recommends, err = fallbackAllCurrentLevel(ctx, rdb, hierarchy) if err != nil { logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: true, IsFallback: true, Err: err, } - return } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: recommends, IsFuzzy: true, @@ -124,165 +153,102 @@ func levelOneRedisSearch(ctx context.Context, rdb *redis.Client, hierarchy const // RedisSearchRecommend define func of redis search by input string and return recommend results func RedisSearchRecommend(ctx context.Context, input string) map[string]SearchResult { rdb := diagram.GetRedisClientInstance() - finalizeResults := func(results map[string]SearchResult) map[string]SearchResult { + finalizeResults := func(normalizeInput string, results map[string]SearchResult) map[string]SearchResult { results = suppressFallbackResultsWhenConcreteHitExists(results) - return normalizeRecommendResults(input, results) + return normalizeRecommendResults(normalizeInput, results) } - if input == "" { - fanInChan := make(chan SearchResult, 2) - // return all grid tagname - go getAllKeyByGridLevel(ctx, rdb, fanInChan) - // return all component nspath - go getAllKeyByNSPathLevel(ctx, rdb, fanInChan) - results := make(map[string]SearchResult) - for range 2 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "return all keys at the special level from redis failed", "recommend_type", result.RecommendType, "error", result.Err) - continue - } - - if result.RecommendType == constants.CompNSPathRecommendHierarchyType { - result.QueryDatas = filterLocalNSPathResults(result.QueryDatas) - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + if input == "" || shouldFallbackToInitialRecommend(input) { + results := runRecommendSearches(ctx, "return all keys at the special level from redis failed", true, + func() SearchResult { + return getAllKeyByGridLevel(ctx, rdb) + }, + func() SearchResult { + return getAllKeyByNSPathLevel(ctx, rdb) + }, + ) + return finalizeResults("", results) } inputSlice := strings.Split(input, ".") inputSliceLen := len(inputSlice) - fanInChan := make(chan SearchResult, 4) switch inputSliceLen { case 1: searchInput := inputSlice[0] - // grid tagname search - go levelOneRedisSearch(ctx, rdb, constants.GridRecommendHierarchyType, constants.FullRecommendLength, searchInput, constants.RedisAllGridSetKey, fanInChan) - // component nspath search - go levelOneRedisSearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.IsLocalRecommendLength, searchInput, constants.RedisAllCompNSPathSetKey, fanInChan) - - results := make(map[string]SearchResult) - // TODO 后续根据支持的数据标识语法长度,进行值的变更 - for range 2 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "exec redis fuzzy search by key failed", "recommend_type", result.RecommendType, "error", result.Err) - continue - } - - if result.RecommendType == constants.CompNSPathRecommendHierarchyType { - result.QueryDatas = filterLocalNSPathResults(result.QueryDatas) - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "exec redis fuzzy search by key failed", true, + func() SearchResult { + return levelOneRedisSearch(ctx, rdb, constants.GridRecommendHierarchyType, constants.FullRecommendLength, searchInput, constants.RedisAllGridSetKey) + }, + func() SearchResult { + return levelOneRedisSearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.IsLocalRecommendLength, searchInput, constants.RedisAllCompNSPathSetKey) + }, + ) + return finalizeResults(input, results) case 2: - // zone tagname search - go handleLevelFuzzySearch(ctx, rdb, constants.ZoneRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllZoneSetKey, inputSlice, fanInChan) - // component tagname search - go handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllCompTagSetKey, inputSlice, fanInChan) - // measurement tagname search by token4-token7 shorthand - go handleNSPathMeasSearch(ctx, rdb, inputSlice, fanInChan) - results := make(map[string]SearchResult) - for range 3 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.ZoneRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllZoneSetKey, inputSlice) + }, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllCompTagSetKey, inputSlice) + }, + func() SearchResult { + return handleNSPathMeasSearch(ctx, rdb, inputSlice) + }, + ) + return finalizeResults(input, results) case 3: - // station tanname search - go handleLevelFuzzySearch(ctx, rdb, constants.StationRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllStationSetKey, inputSlice, fanInChan) - // config search - go handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan) - - results := make(map[string]SearchResult) - for range 2 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.StationRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllStationSetKey, inputSlice) + }, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice) + }, + ) + return finalizeResults(input, results) case 4: - // component nspath search - go handleLevelFuzzySearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompNSPathSetKey, inputSlice, fanInChan) - // measurement tagname search - go handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan) - - results := make(map[string]SearchResult) - for range 2 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.CompNSPathRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompNSPathSetKey, inputSlice) + }, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.IsLocalRecommendLength, constants.RedisAllConfigSetKey, inputSlice) + }, + ) + return finalizeResults(input, results) case 5: - // component tagname search - go handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompTagSetKey, inputSlice, fanInChan) - - results := make(map[string]SearchResult) - for range 1 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.CompTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllCompTagSetKey, inputSlice) + }, + ) + return finalizeResults(input, results) case 6: - // config search - go handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllConfigSetKey, inputSlice, fanInChan) - - results := make(map[string]SearchResult) - for range 1 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.ConfigRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllConfigSetKey, inputSlice) + }, + ) + return finalizeResults(input, results) case 7: - // measurement tagname search - go handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllMeasTagSetKey, inputSlice, fanInChan) - - results := make(map[string]SearchResult) - for range 1 { - result := <-fanInChan - if result.Err != nil { - logger.Error(ctx, "query all keys at the special level from redis failed", "query_key", result.RecommendType, "error", result.Err) - continue - } - results[result.RecommendType.String()] = result - } - - return finalizeResults(results) + results := runRecommendSearches(ctx, "query all keys at the special level from redis failed", false, + func() SearchResult { + return handleLevelFuzzySearch(ctx, rdb, constants.MeasTagRecommendHierarchyType, constants.FullRecommendLength, constants.RedisAllMeasTagSetKey, inputSlice) + }, + ) + return finalizeResults(input, results) default: logger.Error(ctx, "unsupport length of search input", "input_len", inputSliceLen) return nil } } +func shouldFallbackToInitialRecommend(input string) bool { + return strings.HasPrefix(input, ".") +} + // suppressFallbackResultsWhenConcreteHitExists 有明确命中时丢弃兜底结果, 避免返回过宽推荐。 func suppressFallbackResultsWhenConcreteHitExists(results map[string]SearchResult) map[string]SearchResult { hasConcreteHit := false @@ -494,23 +460,22 @@ func getAllSetKeyByHierarchy(hierarchy constants.RecommendHierarchyType) (string } // getAllKeyByGridLevel 返回所有 grid tag, 用于空输入时的初始推荐。 -func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client, fanInChan chan SearchResult) { +func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client) SearchResult { setKey := constants.RedisAllGridSetKey hierarchy := constants.GridRecommendHierarchyType members, err := rdb.SMembers(ctx, setKey).Result() if err != nil && err != redigo.ErrNil { logger.Error(ctx, "get all members from redis by special key failed", "key", setKey, "op", "SMembers", "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: members, IsFuzzy: false, @@ -519,23 +484,22 @@ func getAllKeyByGridLevel(ctx context.Context, rdb *redis.Client, fanInChan chan } // getAllKeyByNSPathLevel 返回所有组件 nspath, 用于空输入时的初始推荐。 -func getAllKeyByNSPathLevel(ctx context.Context, rdb *redis.Client, fanInChan chan SearchResult) { +func getAllKeyByNSPathLevel(ctx context.Context, rdb *redis.Client) SearchResult { queryKey := constants.RedisAllCompNSPathSetKey hierarchy := constants.CompNSPathRecommendHierarchyType members, err := rdb.SMembers(ctx, queryKey).Result() if err != nil && err != redigo.ErrNil { logger.Error(ctx, "get all members by special key failed", "key", queryKey, "op", "SMembers", "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: members, IsFuzzy: false, @@ -611,7 +575,7 @@ func getSpecificKeyByLength(hierarchy constants.RecommendHierarchyType, keyPrefi } // handleNSPathMeasSearch 处理 nspath.measurement 的简写搜索路径。 -func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice []string, fanInChan chan SearchResult) { +func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice []string) SearchResult { hierarchy := constants.MeasTagRecommendHierarchyType nsPath := inputSlice[0] searchInput := inputSlice[1] @@ -619,22 +583,20 @@ func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice [ nsPathExists, err := rdb.SIsMember(ctx, constants.RedisAllCompNSPathSetKey, nsPath).Result() if err != nil { logger.Error(ctx, "check nspath exist from redis set failed", "key", constants.RedisAllCompNSPathSetKey, "nspath", nsPath, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } if !nsPathExists { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: []string{}, IsFuzzy: false, Err: nil, } - return } queryKey := fmt.Sprintf(constants.RedisSpecCompNSPathMeasSetKey, nsPath) @@ -642,57 +604,52 @@ func handleNSPathMeasSearch(ctx context.Context, rdb *redis.Client, inputSlice [ members, err := rdb.SMembers(ctx, queryKey).Result() if err != nil && err != redis.Nil { logger.Error(ctx, "query measurement tags by nspath failed", "key", queryKey, "nspath", nsPath, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: combineNSPathMeasResults(nsPath, members), IsFuzzy: false, Err: nil, } - return } measTagExists, err := rdb.SIsMember(ctx, queryKey, searchInput).Result() if err != nil { logger.Error(ctx, "check measurement tag exist from nspath set failed", "key", queryKey, "meas_tag", searchInput, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } if measTagExists { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: []string{""}, IsFuzzy: false, Err: nil, } - return } recommends, offset, err := runNSPathMeasFuzzySearch(ctx, nsPath, searchInput) if err != nil { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: true, Err: err, } - return } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: recommends, IsFuzzy: true, @@ -760,7 +717,7 @@ func splitLastToken(term string) (string, string) { } // handleLevelFuzzySearch 处理第二层及以后层级的精确、模糊和兜底推荐。 -func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, redisSetKey string, inputSlice []string, fanInChan chan SearchResult) { +func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, redisSetKey string, inputSlice []string) SearchResult { inputSliceLen := len(inputSlice) searchInputIndex := inputSliceLen - 1 searchInput := inputSlice[searchInputIndex] @@ -783,36 +740,33 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co keyExists, err := rdb.SIsMember(ctx, redisSetKey, specificalKey).Result() if err != nil { logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } if !keyExists { - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: []string{}, IsFuzzy: false, Err: nil, } - return } } members, err := queryMemberFromSpecificsLevel(ctx, rdb, hierarchy, specificalKey) if err != nil && err != redis.Nil { logger.Error(ctx, "query members from redis by special key failed", "key", specificalKey, "member", searchInput, "op", "SMember", "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } recommandResults := combineQueryResultByInput(hierarchy, recommendLenType, inputSlice, members) @@ -838,25 +792,23 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co } recommandResults = secondConfirmResults } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: recommandResults, IsFuzzy: false, Err: nil, } - return } keyExists, err := rdb.SIsMember(ctx, redisSetKey, searchInput).Result() if err != nil { logger.Error(ctx, "check key exist from redis set failed ", "key", redisSetKey, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } if keyExists { @@ -867,26 +819,24 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co QueryData = []string{"."} } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: QueryData, IsFuzzy: false, Err: nil, } - return } // start redis fuzzy search recommends, offset, err := runFuzzySearch(ctx, rdb, searchInput, searchPrefix, hierarchy, recommendLenType) if err != nil { logger.Error(ctx, "fuzzy search failed by hierarchy", "hierarchy", hierarchy, "search_input", searchInput, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: false, Err: err, } - return } isFallback := false @@ -895,20 +845,19 @@ func handleLevelFuzzySearch(ctx context.Context, rdb *redis.Client, hierarchy co recommends, err = fallbackCurrentLevelByInput(ctx, rdb, hierarchy, inputSlice) if err != nil { logger.Error(ctx, "fallback all keys at current level failed", "hierarchy", hierarchy, "search_input", searchInput, "error", err) - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: nil, IsFuzzy: true, IsFallback: true, Err: err, } - return } isFallback = true offset = 0 } - fanInChan <- SearchResult{ + return SearchResult{ RecommendType: hierarchy, QueryDatas: recommends, IsFuzzy: true, @@ -992,7 +941,7 @@ func runFuzzySearch(ctx context.Context, rdb *redis.Client, searchInput string, } if termHierarchyLen == compareHierarchyLen && termPrefix == comparePrefix && strings.HasPrefix(termLastPart, searchInput) { - exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, recommendLenType, comparePrefix, termLastPart) + exists, err := fuzzyRecommendMemberExists(ctx, rdb, hierarchy, comparePrefix, termLastPart) if err != nil || !exists { logger.Info(ctx, "fuzzy recommend term not found in specific redis set", "hierarchy", hierarchy, @@ -1034,8 +983,8 @@ func fuzzyRecommendOffset(searchPrefix string, searchInput string) int { } // fuzzyRecommendMemberExists 校验模糊候选末级 token 是否存在于对应 Redis set。 -func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, recommendLenType string, comparePrefix string, termLastPart string) (bool, error) { - setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, recommendLenType, comparePrefix) +func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarchy constants.RecommendHierarchyType, comparePrefix string, termLastPart string) (bool, error) { + setKey, ok := fuzzyRecommendMemberSetKey(hierarchy, comparePrefix) if !ok { return true, nil } @@ -1043,7 +992,7 @@ func fuzzyRecommendMemberExists(ctx context.Context, rdb *redis.Client, hierarch } // fuzzyRecommendMemberSetKey 返回模糊候选校验时应使用的 Redis set key。 -func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, recommendLenType string, comparePrefix string) (string, bool) { +func fuzzyRecommendMemberSetKey(hierarchy constants.RecommendHierarchyType, comparePrefix string) (string, bool) { switch hierarchy { case constants.GridRecommendHierarchyType: return constants.RedisAllGridSetKey, true diff --git a/util/time.go b/util/time.go index f51b210..7c75e99 100644 --- a/util/time.go +++ b/util/time.go @@ -6,8 +6,8 @@ import ( "time" ) -// GenNanoTsStr define func to generate nanosecond timestamp string by current time -func GenNanoTsStr() string { +// GenNanoTSStr define func to generate nanosecond timestamp string by current time +func GenNanoTSStr() string { now := time.Now() nanoseconds := now.UnixNano() timestampStr := strconv.FormatInt(nanoseconds, 10)