Implement asynchronous AI recommendation cache refresh in company service
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
- Introduced `refreshAIRecommendationsCacheAsync` method to refresh AI recommendations in the background, improving responsiveness by serving the previous cache until the refresh completes. - Updated `StartAIOnboarding` to call the new asynchronous cache refresh method instead of invalidating the cache directly. - Added logging for cache refresh operations, including success and error handling, to enhance observability. This update enhances the AI recommendation caching mechanism, providing a smoother onboarding experience and reducing latency in recommendation retrieval.
This commit is contained in:
@@ -85,7 +85,8 @@ func (s *companyService) StartAIOnboarding(ctx context.Context, companyID string
|
|||||||
return nil, fmt.Errorf("failed to start AI onboarding: %w", err)
|
return nil, fmt.Errorf("failed to start AI onboarding: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.invalidateAIRecommendationCache(ctx, companyID)
|
// Prefetch recommendations in the background; keep serving the previous cache until refresh completes.
|
||||||
|
s.refreshAIRecommendationsCacheAsync(companyID)
|
||||||
|
|
||||||
return &OnboardingResponse{Status: result.Status}, nil
|
return &OnboardingResponse{Status: result.Status}, nil
|
||||||
}
|
}
|
||||||
@@ -143,6 +144,48 @@ func (s *companyService) GetAIRecommendations(ctx context.Context, companyID str
|
|||||||
return nil, errors.New("company not found")
|
return nil, errors.New("company not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return s.fetchAndCacheAIRecommendations(ctx, companyID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *companyService) refreshAIRecommendationsCacheAsync(companyID string) {
|
||||||
|
if s.aiRecommendationClient == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
companyID = strings.TrimSpace(companyID)
|
||||||
|
if companyID == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
s.logger.Info("Refreshing AI recommendation cache in background", map[string]interface{}{
|
||||||
|
"company_id": companyID,
|
||||||
|
})
|
||||||
|
|
||||||
|
if _, err := s.repository.GetByID(ctx, companyID); err != nil {
|
||||||
|
s.logger.Error("Failed to load company for AI recommendation refresh", map[string]interface{}{
|
||||||
|
"company_id": companyID,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.fetchAndCacheAIRecommendations(ctx, companyID); err != nil {
|
||||||
|
s.logger.Error("Failed to refresh AI recommendation cache", map[string]interface{}{
|
||||||
|
"company_id": companyID,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.logger.Info("AI recommendation cache refreshed", map[string]interface{}{
|
||||||
|
"company_id": companyID,
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *companyService) fetchAndCacheAIRecommendations(ctx context.Context, companyID string) ([]RecommendedTenderResponse, error) {
|
||||||
s.logger.Info("Fetching AI tender recommendations", map[string]interface{}{
|
s.logger.Info("Fetching AI tender recommendations", map[string]interface{}{
|
||||||
"company_id": companyID,
|
"company_id": companyID,
|
||||||
})
|
})
|
||||||
@@ -228,19 +271,6 @@ func (s *companyService) cacheAIRecommendations(ctx context.Context, companyID s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *companyService) invalidateAIRecommendationCache(ctx context.Context, companyID string) {
|
|
||||||
if s.redisClient == nil || s.recommendationCacheTTL <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.redisClient.Del(ctx, aiRecommendationCacheKey(companyID)); err != nil {
|
|
||||||
s.logger.Warn("Failed to invalidate AI recommendation cache", map[string]interface{}{
|
|
||||||
"company_id": companyID,
|
|
||||||
"error": err.Error(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *companyService) buildOnboardingDocuments(fileIDs []string) (string, error) {
|
func (s *companyService) buildOnboardingDocuments(fileIDs []string) (string, error) {
|
||||||
if len(fileIDs) == 0 {
|
if len(fileIDs) == 0 {
|
||||||
return "[]", nil
|
return "[]", nil
|
||||||
|
|||||||
Reference in New Issue
Block a user