discourse/plugins/discourse-ai/lib/translation/category_localizer.rb
Rafael dos Santos Silva 0b73d7ac1a
PERF: Cache LlmModel lookups in backfill jobs (#36359)
Backfill jobs were fetching the same LlmModel on every loop iteration,
causing N+1 queries. For a batch of 100 items, this meant 100+ identical
SQL queries to populate the same LlmModel object.

## Changes

- Cache LlmModel once per job execution in summaries and translation
backfills
- Pass cached model through to summarization and translation methods via
optional parameters
- Add tests verifying models are queried once per batch instead of once
per item

## Impact

**Before:** For 100 items, 100+ `LlmModel.find_by()` queries  
**After:** For 100 items, 1-2 queries total

All changes are backward compatible - new parameters are optional with
nil defaults, so existing callers continue to work unchanged.
2025-12-01 17:04:25 -03:00

46 lines
1.2 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseAi
module Translation
class CategoryLocalizer
def self.localize(
category,
target_locale = I18n.locale,
short_text_llm_model: nil,
post_raw_llm_model: nil
)
return if category.blank? || target_locale.blank?
target_locale = target_locale.to_s.sub("-", "_")
translated_name =
ShortTextTranslator.new(
text: category.name,
target_locale:,
llm_model: short_text_llm_model,
).translate
translated_description =
if category.description_excerpt.present?
PostRawTranslator.new(
text: category.description_excerpt,
target_locale:,
llm_model: post_raw_llm_model,
).translate
else
""
end
localization =
CategoryLocalization.find_or_initialize_by(
category_id: category.id,
locale: target_locale,
)
localization.name = translated_name
localization.description = translated_description
localization.save!
localization
end
end
end
end