Enhance tender recommendation caching and page refresh logic
continuous-integration/drone/push Build is passing

- Introduced a new `RecommendedTendersPageCacheRefresher` interface to manage the asynchronous refresh of recommendation pages in Redis, improving cache management.
- Updated the `companyService` to support setting page cache languages and refreshing the recommended tenders page cache based on company IDs.
- Enhanced the `tenderService` to build and invalidate recommended tenders page caches, ensuring timely updates and efficient retrieval of cached recommendations.
- Added configuration options for recommendation page cache languages in the `AISummarizerConfig`, allowing for flexible language support.
- Implemented unit tests for the new caching logic and page refresh functionality, ensuring robust validation of the recommendation caching process.

This update significantly improves the efficiency and responsiveness of the tender recommendation service by integrating enhanced caching mechanisms and page refresh capabilities.
This commit is contained in:
Mazyar
2026-07-08 02:05:36 +03:30
parent b28bc23975
commit 0b74e9ad23
11 changed files with 628 additions and 15 deletions
+7
View File
@@ -0,0 +1,7 @@
package company
// RecommendedTendersPageCacheRefresher pre-builds resolved recommendation pages in Redis.
// Implemented by the tender service on the web API; optional on the worker.
type RecommendedTendersPageCacheRefresher interface {
ScheduleRefreshRecommendedTendersPageCache(companyID string)
}
+5
View File
@@ -464,7 +464,11 @@ func (s *companyService) cacheAIRecommendations(ctx context.Context, companyID s
"company_id": companyID,
"error": err.Error(),
})
return
}
s.invalidateRecommendedTendersPageCache(ctx, companyID)
s.scheduleRecommendedTendersPageCacheRefresh(companyID)
}
func (s *companyService) recommendationCacheExpiration() time.Duration {
@@ -485,6 +489,7 @@ func (s *companyService) invalidateAIRecommendationCache(ctx context.Context, co
"error": err.Error(),
})
}
s.invalidateRecommendedTendersPageCache(ctx, companyID)
}
func (s *companyService) buildOnboardingDocuments(fileIDs []string) (string, error) {
@@ -0,0 +1,71 @@
package company
import (
"context"
"strings"
)
const recommendedTendersPageCacheKeyPrefix = "ai:recommendations:page:"
func recommendedTendersPageCacheKey(companyID, language string) string {
return recommendedTendersPageCacheKeyPrefix +
strings.TrimSpace(companyID) + ":" +
strings.ToLower(strings.TrimSpace(language))
}
func (s *companyService) invalidateRecommendedTendersPageCache(ctx context.Context, companyID string) {
if s.redisClient == nil {
return
}
for _, language := range s.pageCacheLanguages {
lang := strings.ToLower(strings.TrimSpace(language))
if lang == "" {
continue
}
_ = s.redisClient.Del(ctx, recommendedTendersPageCacheKey(companyID, lang))
}
}
func (s *companyService) scheduleRecommendedTendersPageCacheRefresh(companyID string) {
if s.pageCacheRefresher == nil {
return
}
s.pageCacheRefresher.ScheduleRefreshRecommendedTendersPageCache(companyID)
}
// SetRecommendedTendersPageCacheRefresher wires async page-cache rebuilds from the tender service.
func (s *companyService) SetRecommendedTendersPageCacheRefresher(refresher RecommendedTendersPageCacheRefresher) {
s.pageCacheRefresher = refresher
}
// SetPageCacheLanguages configures which language variants are invalidated in Redis.
func (s *companyService) SetPageCacheLanguages(languages []string) {
s.pageCacheLanguages = normalizePageCacheLanguages("", languages)
}
func normalizePageCacheLanguages(defaultLanguage string, languages []string) []string {
seen := make(map[string]struct{})
out := make([]string, 0, len(languages)+1)
add := func(lang string) {
lang = strings.ToLower(strings.TrimSpace(lang))
if lang == "" {
return
}
if _, ok := seen[lang]; ok {
return
}
seen[lang] = struct{}{}
out = append(out, lang)
}
add(defaultLanguage)
for _, lang := range languages {
add(lang)
}
if len(out) == 0 {
out = append(out, "en")
}
return out
}
+2
View File
@@ -60,8 +60,10 @@ type companyService struct {
fileStore filestore.FileStoreService
aiRecommendationClient AIRecommendationClient
aiPipelineStatusClient AIPipelineStatusClient
pageCacheRefresher RecommendedTendersPageCacheRefresher
redisClient redis.Client
recommendationCacheTTL time.Duration
pageCacheLanguages []string
logger logger.Logger
}