Configurable workers and move sweeper job to job infra (#35007)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions

This commit is contained in:
Ben Cooke 2026-02-02 15:52:42 -05:00 committed by GitHub
parent 95ba2db4f0
commit 36479bd721
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 74 additions and 0 deletions

View file

@ -849,6 +849,7 @@ const defaultServerConfig: AdminConfig = {
APIKey: '',
},
TargetLanguages: ['en'],
Workers: 4,
TimeoutMs: 5000,
Agents: {
LLMServiceID: '',

View file

@ -1488,6 +1488,12 @@ func (s *Server) initJobs() {
s.Jobs.RegisterJobType(model.JobTypePushProxyAuth, builder.MakeWorker(), builder.MakeScheduler())
}
if s.AutoTranslation != nil {
s.Jobs.RegisterJobType(model.JobTypeAutoTranslationRecovery,
s.AutoTranslation.MakeWorker(),
s.AutoTranslation.MakeScheduler())
}
s.Jobs.RegisterJobType(
model.JobTypeMigrations,
migrations.MakeWorker(s.Jobs, s.Store()),

View file

@ -7,6 +7,7 @@ import (
"context"
"github.com/mattermost/mattermost/server/public/model"
ejobs "github.com/mattermost/mattermost/server/v8/einterfaces/jobs"
)
// AutoTranslationInterface defines the enterprise advanced auto-translation functionality.
@ -75,4 +76,12 @@ type AutoTranslationInterface interface {
// Shutdown gracefully shuts down the auto-translation service.
Shutdown() error
// MakeWorker creates a worker for the autotranslation recovery sweep job.
// The worker picks up stuck translations and re-queues them for processing.
MakeWorker() model.Worker
// MakeScheduler creates a scheduler for the autotranslation recovery sweep job.
// The scheduler runs periodically to detect stuck translations.
MakeScheduler() ejobs.Scheduler
}

View file

@ -7,6 +7,8 @@ package mocks
import (
context "context"
jobs "github.com/mattermost/mattermost/server/v8/einterfaces/jobs"
mock "github.com/stretchr/testify/mock"
model "github.com/mattermost/mattermost/server/public/model"
@ -214,6 +216,46 @@ func (_m *AutoTranslationInterface) IsUserEnabled(channelID string, userID strin
return r0, r1
}
// MakeScheduler provides a mock function with no fields
func (_m *AutoTranslationInterface) MakeScheduler() jobs.Scheduler {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for MakeScheduler")
}
var r0 jobs.Scheduler
if rf, ok := ret.Get(0).(func() jobs.Scheduler); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(jobs.Scheduler)
}
}
return r0
}
// MakeWorker provides a mock function with no fields
func (_m *AutoTranslationInterface) MakeWorker() model.Worker {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for MakeWorker")
}
var r0 model.Worker
if rf, ok := ret.Get(0).(func() model.Worker); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(model.Worker)
}
}
return r0
}
// SetChannelEnabled provides a mock function with given fields: channelID, enabled
func (_m *AutoTranslationInterface) SetChannelEnabled(channelID string, enabled bool) *model.AppError {
ret := _m.Called(channelID, enabled)

View file

@ -9904,6 +9904,10 @@
"id": "model.config.is_valid.autotranslation.timeout.app_error",
"translation": "Invalid timeout for autotranslation settings. Must be a positive number."
},
{
"id": "model.config.is_valid.autotranslation.workers.app_error",
"translation": "Workers must be between 1 and 32."
},
{
"id": "model.config.is_valid.cache_type.app_error",
"translation": "Cache type must be either lru or redis."

View file

@ -2787,6 +2787,7 @@ type AutoTranslationSettings struct {
Enable *bool `access:"site_localization,cloud_restrictable"`
Provider *string `access:"site_localization,cloud_restrictable"`
TargetLanguages *[]string `access:"site_localization,cloud_restrictable"`
Workers *int `access:"site_localization,cloud_restrictable"`
TimeoutMs *int `access:"site_localization,cloud_restrictable"`
LibreTranslate *LibreTranslateProviderSettings `access:"site_localization,cloud_restrictable"`
Agents *AgentsProviderSettings `access:"site_localization,cloud_restrictable"`
@ -2815,6 +2816,10 @@ func (s *AutoTranslationSettings) SetDefaults() {
s.TargetLanguages = &[]string{"en"}
}
if s.Workers == nil {
s.Workers = NewPointer(4)
}
if s.TimeoutMs == nil {
s.TimeoutMs = NewPointer(5000)
}
@ -4823,6 +4828,11 @@ func (s *AutoTranslationSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.autotranslation.timeout.app_error", nil, "", http.StatusBadRequest)
}
// Validate workers if set (must be between 1 and 32)
if s.Workers != nil && (*s.Workers < 1 || *s.Workers > 32) {
return NewAppError("Config.IsValid", "model.config.is_valid.autotranslation.workers.app_error", nil, "", http.StatusBadRequest)
}
return nil
}

View file

@ -47,6 +47,7 @@ const (
JobTypePushProxyAuth = "push_proxy_auth"
JobTypeRecap = "recap"
JobTypeDeleteExpiredPosts = "delete_expired_posts"
JobTypeAutoTranslationRecovery = "autotranslation_recovery"
JobStatusPending = "pending"
JobStatusInProgress = "in_progress"

View file

@ -755,6 +755,7 @@ export type LocalizationSettings = {
export type AutoTranslationSettings = {
Enable: boolean;
TargetLanguages: string[];
Workers: number;
Provider: '' | 'libretranslate' | 'agents';
LibreTranslate: {
URL: string;