Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ The operator is part of Tern orchestration. The API service starts it on server

Each operator driver runs immediately on startup, then polls every 10 seconds. The driver claims at most one apply per tick and resumes it through the Tern client for that apply's deployment and environment. Fresh applies also send a best-effort wake signal after their apply and task rows are committed, so a driver can claim them immediately instead of waiting for the next poll tick.

`drivers` controls operator concurrency (the deprecated `operator_workers` and `scheduler_workers` aliases are still accepted for one release). The default is four drivers, so an untuned server can still make progress across independent databases and environments concurrently. More drivers help larger installations with many independent schema changes because each driver can claim and resume a different target during the same operator tick.
`drivers` controls operator concurrency. The default is four drivers, so an untuned server can still make progress across independent databases and environments concurrently. More drivers help larger installations with many independent schema changes because each driver can claim and resume a different target during the same operator tick.

In a multi-pod deployment, every SchemaBot pod runs its own operator. Each operator has its own configurable driver pool, and every driver coordinates through shared storage before resuming an apply. When a recovered apply came from a PR comment, the driver attaches a reconstructed `ProgressObserver` before calling `ResumeApply()` so the resumed progress poller can keep updating PR comments.

Expand Down
2 changes: 0 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ Increase `drivers` when one SchemaBot server should make operator progress acros

A driver claim means selecting one stale apply and refreshing its heartbeat in the same storage transaction. That heartbeat refresh is the driver's lease while it reloads state and drives the apply to a terminal state.

> **Deprecated:** the previous `operator_workers` and `scheduler_workers` keys still work as aliases for `drivers` and are honored with a deprecation warning. Set only one of the three. The aliases will be removed one release after the driver rename has soaked.

## Pending Drops

For MySQL databases executed by the Spirit engine, `DROP TABLE` statements are
Expand Down
54 changes: 1 addition & 53 deletions pkg/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,7 @@ type ServerConfig struct {
// SKIP LOCKED to prevent races. Defaults to DefaultDrivers.
Drivers int `yaml:"drivers"`

// OperatorWorkers is the deprecated alias for Drivers. It is kept so existing
// config files that still set operator_workers continue to load (the YAML
// decoder runs with KnownFields(true) and would otherwise reject the unknown
// key). Validate() folds it into Drivers when the new key is unset and logs a
// deprecation warning. Remove one release after the driver rename has soaked.
//
// Deprecated: use drivers.
OperatorWorkers int `yaml:"operator_workers,omitempty"`

// SchedulerWorkers is the original deprecated alias for Drivers, predating
// operator_workers. It is kept for the same KnownFields(true) reason and is
// folded into Drivers by Validate() with a deprecation warning.
//
// Deprecated: use drivers.
SchedulerWorkers int `yaml:"scheduler_workers,omitempty"`

// OperatorClaimOperations switches operator drivers to claim work at the
// OperatorClaimOperations switches drivers to claim work at the
// apply_operations (per-deployment) level via FindNextApplyOperation instead
// of the apply level via FindNextApply. While every apply still owns exactly
// one operation, the operation-scoped drive resolves to the same work as the
Expand Down Expand Up @@ -720,44 +704,8 @@ func LoadServerConfigFromFile(path string) (*ServerConfig, error) {
return &config, nil
}

// resolveDeprecatedDrivers folds the deprecated operator_workers and
// scheduler_workers keys into drivers. When only a deprecated key is set it is
// honored and a deprecation warning is logged; setting more than one of the
// three keys is rejected so the effective value is never ambiguous.
func (c *ServerConfig) resolveDeprecatedDrivers() error {
set := 0
if c.Drivers != 0 {
set++
}
if c.OperatorWorkers != 0 {
set++
}
if c.SchedulerWorkers != 0 {
set++
}
if set > 1 {
return fmt.Errorf("set only one of drivers, operator_workers, or scheduler_workers (operator_workers and scheduler_workers are deprecated)")
}

if c.OperatorWorkers != 0 {
slog.Warn("operator_workers is deprecated; use drivers", "operator_workers", c.OperatorWorkers)
c.Drivers = c.OperatorWorkers
c.OperatorWorkers = 0
}
if c.SchedulerWorkers != 0 {
slog.Warn("scheduler_workers is deprecated; use drivers", "scheduler_workers", c.SchedulerWorkers)
c.Drivers = c.SchedulerWorkers
c.SchedulerWorkers = 0
}
return nil
}

// Validate checks the configuration for required fields and consistency.
func (c *ServerConfig) Validate() error {
if err := c.resolveDeprecatedDrivers(); err != nil {
return err
}

// The database registry is required for the control plane and for a
// single-database data plane. A data plane configured with a target_resolver
// resolves opaque targets dynamically and has no database registry, so it is
Expand Down
19 changes: 0 additions & 19 deletions pkg/api/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,6 @@ func TestDriversConfig(t *testing.T) {
config := &ServerConfig{Drivers: 3}
assert.Equal(t, 3, config.Drivers)
})

t.Run("deprecated operator_workers folds into drivers", func(t *testing.T) {
config := &ServerConfig{OperatorWorkers: 2}
require.NoError(t, config.resolveDeprecatedDrivers())
assert.Equal(t, 2, config.Drivers)
assert.Equal(t, 0, config.OperatorWorkers)
})

t.Run("deprecated scheduler_workers folds into drivers", func(t *testing.T) {
config := &ServerConfig{SchedulerWorkers: 2}
require.NoError(t, config.resolveDeprecatedDrivers())
assert.Equal(t, 2, config.Drivers)
assert.Equal(t, 0, config.SchedulerWorkers)
})

t.Run("setting multiple keys is rejected", func(t *testing.T) {
config := &ServerConfig{Drivers: 4, OperatorWorkers: 2}
assert.Error(t, config.resolveDeprecatedDrivers())
})
}

// recordingApplyOperationStore records the state-mutating call made by
Expand Down
Loading