@@ -28,6 +28,16 @@ const (
2828 defaultExpiryCleanupInterval = 1 * time .Second
2929 // defaultEnqueueChannelBufferSize is the default size of a worker's incoming request buffer.
3030 defaultEnqueueChannelBufferSize = 100
31+ // defaultMaxRevocationsPerDecision caps revocations per reclamation decision, bounding the
32+ // damage from mean-footprint misestimation.
33+ defaultMaxRevocationsPerDecision = 2
34+ // defaultEvictionConfirmationGrace covers the reclaiming stage (engine abort, KV GC, scrape,
35+ // staleness window) for the default utilization detector. Deployments pairing eviction with the
36+ // concurrency detector can lower it substantially.
37+ defaultEvictionConfirmationGrace = 500 * time .Millisecond
38+ // defaultEvictionConfirmationTimeout bounds how long an unconfirmed revocation can hold the
39+ // reclamation pacing gate closed.
40+ defaultEvictionConfirmationTimeout = 10 * time .Second
3141)
3242
3343// Config holds the configuration for the `FlowController`.
@@ -46,6 +56,33 @@ type Config struct {
4656 // serial execution loop and allowing the system to handle short bursts of traffic without blocking.
4757 // Optional: Defaults to `defaultEnqueueChannelBufferSize` (100).
4858 EnqueueChannelBufferSize int
59+
60+ // EnableEviction enables demand-driven in-flight eviction: when higher-priority requests are
61+ // blocked by pool saturation, lower-priority in-flight requests may be terminated to reclaim
62+ // capacity. Requires the eviction plumbing to be wired (see Deps.InFlightEvictor).
63+ // See docs/flow-control-eviction.md.
64+ // Optional: Defaults to false.
65+ EnableEviction bool
66+
67+ // MaxRevocationsPerDecision caps how many revocations a single reclamation decision may issue.
68+ // Not exposed through the API configuration: benchmark data shows sizing is deficit-bound, so
69+ // this cap rarely binds and is not worth a user-facing knob.
70+ // Optional: Defaults to `defaultMaxRevocationsPerDecision` (2).
71+ MaxRevocationsPerDecision int
72+
73+ // EvictionConfirmationGrace is how long a confirmed revocation's pending-reclaim debit keeps
74+ // suppressing further reclamation, covering the saturation signal's confirmation-to-visibility
75+ // lag. Not exposed through the API configuration: the EPP wiring derives it from the selected
76+ // saturation detector, since the correct value is a property of the sensor, not a preference.
77+ // Optional: Defaults to `defaultEvictionConfirmationGrace` (500ms), the conservative value for
78+ // scraped sensors.
79+ EvictionConfirmationGrace time.Duration
80+
81+ // EvictionConfirmationTimeout bounds how long an unconfirmed revocation can hold the
82+ // reclamation pacing gate closed before being treated as confirmed. Not exposed through the
83+ // API configuration.
84+ // Optional: Defaults to `defaultEvictionConfirmationTimeout` (10s).
85+ EvictionConfirmationTimeout time.Duration
4986}
5087
5188func (c * Config ) String () string {
@@ -64,20 +101,26 @@ type ConfigOption func(*Config)
64101
65102// NewConfigFromAPI creates a new Config from the API configuration.
66103func NewConfigFromAPI (apiConfig * configapi.FlowControlConfig ) (* Config , error ) {
67- opts := make ([]ConfigOption , 0 , 1 )
104+ opts := make ([]ConfigOption , 0 , 4 )
68105 if apiConfig != nil {
69106 if apiConfig .DefaultRequestTTL != nil {
70107 opts = append (opts , WithDefaultRequestTTL (apiConfig .DefaultRequestTTL .Duration ))
71108 }
109+ if apiConfig .EnableEviction {
110+ opts = append (opts , WithEnableEviction (true ))
111+ }
72112 }
73113 return NewConfig (opts ... )
74114}
75115
76116// NewConfig creates a new Config with the given options, applying defaults and validation.
77117func NewConfig (opts ... ConfigOption ) (* Config , error ) {
78118 c := & Config {
79- ExpiryCleanupInterval : defaultExpiryCleanupInterval ,
80- EnqueueChannelBufferSize : defaultEnqueueChannelBufferSize ,
119+ ExpiryCleanupInterval : defaultExpiryCleanupInterval ,
120+ EnqueueChannelBufferSize : defaultEnqueueChannelBufferSize ,
121+ MaxRevocationsPerDecision : defaultMaxRevocationsPerDecision ,
122+ EvictionConfirmationGrace : defaultEvictionConfirmationGrace ,
123+ EvictionConfirmationTimeout : defaultEvictionConfirmationTimeout ,
81124 }
82125
83126 for _ , opt := range opts {
@@ -111,6 +154,34 @@ func WithEnqueueChannelBufferSize(size int) ConfigOption {
111154 }
112155}
113156
157+ // WithEnableEviction enables demand-driven in-flight eviction.
158+ func WithEnableEviction (enabled bool ) ConfigOption {
159+ return func (c * Config ) {
160+ c .EnableEviction = enabled
161+ }
162+ }
163+
164+ // WithMaxRevocationsPerDecision sets the per-decision revocation cap.
165+ func WithMaxRevocationsPerDecision (n int ) ConfigOption {
166+ return func (c * Config ) {
167+ c .MaxRevocationsPerDecision = n
168+ }
169+ }
170+
171+ // WithEvictionConfirmationGrace sets the post-confirmation grace period.
172+ func WithEvictionConfirmationGrace (d time.Duration ) ConfigOption {
173+ return func (c * Config ) {
174+ c .EvictionConfirmationGrace = d
175+ }
176+ }
177+
178+ // WithEvictionConfirmationTimeout sets the confirmation timeout.
179+ func WithEvictionConfirmationTimeout (d time.Duration ) ConfigOption {
180+ return func (c * Config ) {
181+ c .EvictionConfirmationTimeout = d
182+ }
183+ }
184+
114185// validate checks the configuration for validity.
115186func (c * Config ) validate () error {
116187 if c .DefaultRequestTTL < 0 {
@@ -122,5 +193,14 @@ func (c *Config) validate() error {
122193 if c .EnqueueChannelBufferSize < 0 {
123194 return fmt .Errorf ("EnqueueChannelBufferSize cannot be negative, but got %d" , c .EnqueueChannelBufferSize )
124195 }
196+ if c .MaxRevocationsPerDecision < 1 {
197+ return fmt .Errorf ("MaxRevocationsPerDecision must be at least 1, but got %d" , c .MaxRevocationsPerDecision )
198+ }
199+ if c .EvictionConfirmationGrace < 0 {
200+ return fmt .Errorf ("EvictionConfirmationGrace cannot be negative, but got %v" , c .EvictionConfirmationGrace )
201+ }
202+ if c .EvictionConfirmationTimeout <= 0 {
203+ return fmt .Errorf ("EvictionConfirmationTimeout must be positive, but got %v" , c .EvictionConfirmationTimeout )
204+ }
125205 return nil
126206}
0 commit comments