feat(core): implement sync outbox mechanism and refactor provider validation

- Introduce `SyncOutboxService` and model to retry failed CP-to-Redis sync operations
- Update `SyncService` to handle sync failures by enqueuing tasks to the outbox
- Centralize provider group and API key validation logic into `ProviderGroupManager`
- Refactor API handlers to utilize the new manager and robust sync methods
- Add configuration options for sync outbox (interval, batch size, retries)
This commit is contained in:
zenfun
2025-12-25 01:24:19 +08:00
parent 44a82fa252
commit 6a16712b9d
12 changed files with 750 additions and 113 deletions

View File

@@ -19,6 +19,7 @@ type Config struct {
ModelRegistry ModelRegistryConfig
Quota QuotaConfig
Internal InternalConfig
SyncOutbox SyncOutboxConfig
}
type ServerConfig struct {
@@ -71,6 +72,13 @@ type InternalConfig struct {
StatsToken string
}
type SyncOutboxConfig struct {
Enabled bool
IntervalSeconds int
BatchSize int
MaxRetries int
}
func Load() (*Config, error) {
v := viper.New()
@@ -97,6 +105,10 @@ func Load() (*Config, error) {
v.SetDefault("model_registry.timeout_seconds", 30)
v.SetDefault("quota.reset_interval_seconds", 300)
v.SetDefault("internal.stats_token", "")
v.SetDefault("sync_outbox.enabled", true)
v.SetDefault("sync_outbox.interval_seconds", 5)
v.SetDefault("sync_outbox.batch_size", 200)
v.SetDefault("sync_outbox.max_retries", 10)
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.AutomaticEnv()
@@ -124,6 +136,10 @@ func Load() (*Config, error) {
_ = v.BindEnv("model_registry.timeout_seconds", "EZ_MODEL_REGISTRY_TIMEOUT_SECONDS")
_ = v.BindEnv("quota.reset_interval_seconds", "EZ_QUOTA_RESET_INTERVAL_SECONDS")
_ = v.BindEnv("internal.stats_token", "EZ_INTERNAL_STATS_TOKEN")
_ = v.BindEnv("sync_outbox.enabled", "EZ_SYNC_OUTBOX_ENABLED")
_ = v.BindEnv("sync_outbox.interval_seconds", "EZ_SYNC_OUTBOX_INTERVAL_SECONDS")
_ = v.BindEnv("sync_outbox.batch_size", "EZ_SYNC_OUTBOX_BATCH_SIZE")
_ = v.BindEnv("sync_outbox.max_retries", "EZ_SYNC_OUTBOX_MAX_RETRIES")
if configFile := os.Getenv("EZ_CONFIG_FILE"); configFile != "" {
v.SetConfigFile(configFile)
@@ -182,6 +198,12 @@ func Load() (*Config, error) {
Internal: InternalConfig{
StatsToken: v.GetString("internal.stats_token"),
},
SyncOutbox: SyncOutboxConfig{
Enabled: v.GetBool("sync_outbox.enabled"),
IntervalSeconds: v.GetInt("sync_outbox.interval_seconds"),
BatchSize: v.GetInt("sync_outbox.batch_size"),
MaxRetries: v.GetInt("sync_outbox.max_retries"),
},
}
return cfg, nil