Add default and per-controller max-concurrent-reconciles flags (#4626)

Signed-off-by: KR Ravindra <42912207+KR-Ravindra@users.noreply.github.com>
This commit is contained in:
KR Ravindra
2026-09-09 09:50:13 +02:00
committed by GitHub
parent 7c68e1d318
commit 5e540b6c71
9 changed files with 238 additions and 25 deletions
+41 -4
View File
@@ -10,9 +10,25 @@ import (
// Options is the optional configuration for the controllers, which can be
// set via command-line flags or environment variables.
type Options struct {
// RunnerMaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run
// by the EphemeralRunnerController.
RunnerMaxConcurrentReconciles int
// DefaultMaxConcurrentReconciles is the maximum number of concurrent Reconciles
// applied to every controller that does not have its own value set below.
DefaultMaxConcurrentReconciles int
// AutoscalingRunnerSetMaxConcurrentReconciles is the maximum number of concurrent Reconciles
// which can be run by the AutoscalingRunnerSetController. Zero means DefaultMaxConcurrentReconciles.
AutoscalingRunnerSetMaxConcurrentReconciles int
// AutoscalingListenerMaxConcurrentReconciles is the maximum number of concurrent Reconciles
// which can be run by the AutoscalingListenerController. Zero means DefaultMaxConcurrentReconciles.
AutoscalingListenerMaxConcurrentReconciles int
// EphemeralRunnerSetMaxConcurrentReconciles is the maximum number of concurrent Reconciles
// which can be run by the EphemeralRunnerSetController. Zero means DefaultMaxConcurrentReconciles.
EphemeralRunnerSetMaxConcurrentReconciles int
// EphemeralRunnerMaxConcurrentReconciles is the maximum number of concurrent Reconciles
// which can be run by the EphemeralRunnerController. Zero means DefaultMaxConcurrentReconciles.
EphemeralRunnerMaxConcurrentReconciles int
}
// OptionsWithDefault returns the default options.
@@ -20,10 +36,31 @@ type Options struct {
// rather than having to correlate those in multiple places.
func OptionsWithDefault() Options {
return Options{
RunnerMaxConcurrentReconciles: 2,
DefaultMaxConcurrentReconciles: 1,
}
}
// Resolve returns a copy of the options where a DefaultMaxConcurrentReconciles
// of zero or less is replaced by 1, and every per-controller
// MaxConcurrentReconciles that is left at zero is replaced by
// DefaultMaxConcurrentReconciles.
func (o Options) Resolve() Options {
if o.DefaultMaxConcurrentReconciles <= 0 {
o.DefaultMaxConcurrentReconciles = 1
}
orDefault := func(n int) int {
if n > 0 {
return n
}
return o.DefaultMaxConcurrentReconciles
}
o.AutoscalingRunnerSetMaxConcurrentReconciles = orDefault(o.AutoscalingRunnerSetMaxConcurrentReconciles)
o.AutoscalingListenerMaxConcurrentReconciles = orDefault(o.AutoscalingListenerMaxConcurrentReconciles)
o.EphemeralRunnerSetMaxConcurrentReconciles = orDefault(o.EphemeralRunnerSetMaxConcurrentReconciles)
o.EphemeralRunnerMaxConcurrentReconciles = orDefault(o.EphemeralRunnerMaxConcurrentReconciles)
return o
}
type Option func(*controller.Options)
// WithMaxConcurrentReconciles sets the maximum number of concurrent Reconciles which can be run.
@@ -0,0 +1,43 @@
package actionsgithubcom
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestOptionsResolve(t *testing.T) {
t.Parallel()
t.Run("unset per-controller values fall back to the default", func(t *testing.T) {
got := OptionsWithDefault().Resolve()
assert.Equal(t, 1, got.DefaultMaxConcurrentReconciles)
assert.Equal(t, 1, got.AutoscalingRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 1, got.AutoscalingListenerMaxConcurrentReconciles)
assert.Equal(t, 1, got.EphemeralRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 1, got.EphemeralRunnerMaxConcurrentReconciles)
})
t.Run("a default of zero or less is replaced by 1", func(t *testing.T) {
for _, n := range []int{0, -1} {
opts := Options{DefaultMaxConcurrentReconciles: n}
got := opts.Resolve()
assert.Equal(t, 1, got.DefaultMaxConcurrentReconciles)
assert.Equal(t, 1, got.AutoscalingRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 1, got.AutoscalingListenerMaxConcurrentReconciles)
assert.Equal(t, 1, got.EphemeralRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 1, got.EphemeralRunnerMaxConcurrentReconciles)
}
})
t.Run("a changed default applies to every unset controller", func(t *testing.T) {
opts := OptionsWithDefault()
opts.DefaultMaxConcurrentReconciles = 4
opts.EphemeralRunnerMaxConcurrentReconciles = 20
got := opts.Resolve()
assert.Equal(t, 4, got.AutoscalingRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 4, got.AutoscalingListenerMaxConcurrentReconciles)
assert.Equal(t, 4, got.EphemeralRunnerSetMaxConcurrentReconciles)
assert.Equal(t, 20, got.EphemeralRunnerMaxConcurrentReconciles)
})
}