perf(pages): parallelize bulk AI translation
Run AI translations for multiple languages concurrently using goroutines and sync.WaitGroup. Protects shared counters with mutex. Significantly reduces total translation time when translating many languages. For example, translating 10 languages now takes ~10 seconds instead of ~100 seconds (assuming 10s per language).
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
pages_model "code.gitcaddy.com/server/v3/models/pages"
|
||||
repo_model "code.gitcaddy.com/server/v3/models/repo"
|
||||
@@ -1311,46 +1312,62 @@ func PagesLanguagesPost(ctx *context.Context) {
|
||||
if defaultLang == "" {
|
||||
defaultLang = "en"
|
||||
}
|
||||
var successCount, failCount int
|
||||
var (
|
||||
mu sync.Mutex
|
||||
successCount int
|
||||
failCount int
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
repoID := ctx.Repo.Repository.ID
|
||||
repo := ctx.Repo.Repository
|
||||
for _, lang := range config.I18n.Languages {
|
||||
if lang == defaultLang {
|
||||
continue
|
||||
}
|
||||
translated, err := pages_service.TranslateLandingPageContent(ctx, ctx.Repo.Repository, config, lang)
|
||||
if err != nil {
|
||||
log.Error("AI translation failed for %s: %v", lang, err)
|
||||
failCount++
|
||||
continue
|
||||
}
|
||||
existing, err := pages_model.GetTranslation(ctx, ctx.Repo.Repository.ID, lang)
|
||||
if err != nil {
|
||||
log.Error("GetTranslation failed for %s: %v", lang, err)
|
||||
failCount++
|
||||
continue
|
||||
}
|
||||
if existing != nil {
|
||||
existing.ConfigJSON = translated
|
||||
existing.AutoGenerated = true
|
||||
if err := pages_model.UpdateTranslation(ctx, existing); err != nil {
|
||||
log.Error("UpdateTranslation failed for %s: %v", lang, err)
|
||||
wg.Add(1)
|
||||
go func(lang string) {
|
||||
defer wg.Done()
|
||||
translated, err := pages_service.TranslateLandingPageContent(ctx, repo, config, lang)
|
||||
if err != nil {
|
||||
log.Error("AI translation failed for %s: %v", lang, err)
|
||||
mu.Lock()
|
||||
failCount++
|
||||
continue
|
||||
mu.Unlock()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
t := &pages_model.Translation{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Lang: lang,
|
||||
ConfigJSON: translated,
|
||||
AutoGenerated: true,
|
||||
}
|
||||
if err := pages_model.CreateTranslation(ctx, t); err != nil {
|
||||
log.Error("CreateTranslation failed for %s: %v", lang, err)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
existing, err := pages_model.GetTranslation(ctx, repoID, lang)
|
||||
if err != nil {
|
||||
log.Error("GetTranslation failed for %s: %v", lang, err)
|
||||
failCount++
|
||||
continue
|
||||
return
|
||||
}
|
||||
}
|
||||
successCount++
|
||||
if existing != nil {
|
||||
existing.ConfigJSON = translated
|
||||
existing.AutoGenerated = true
|
||||
if err := pages_model.UpdateTranslation(ctx, existing); err != nil {
|
||||
log.Error("UpdateTranslation failed for %s: %v", lang, err)
|
||||
failCount++
|
||||
return
|
||||
}
|
||||
} else {
|
||||
t := &pages_model.Translation{
|
||||
RepoID: repoID,
|
||||
Lang: lang,
|
||||
ConfigJSON: translated,
|
||||
AutoGenerated: true,
|
||||
}
|
||||
if err := pages_model.CreateTranslation(ctx, t); err != nil {
|
||||
log.Error("CreateTranslation failed for %s: %v", lang, err)
|
||||
failCount++
|
||||
return
|
||||
}
|
||||
}
|
||||
successCount++
|
||||
}(lang)
|
||||
}
|
||||
wg.Wait()
|
||||
if failCount == 0 {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.pages.ai_translate_all_success", successCount))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user