@@ -86,24 +86,19 @@ type Config struct {
8686 // Default: 15 seconds (matches server-side eviction timeout)
8787 HandoffTimeout time.Duration
8888
89- // MinWorkers is the minimum number of worker goroutines for processing handoff requests.
90- // The processor starts with this number of workers and scales down to this level when idle.
91- // If zero, defaults to max(1, PoolSize/50) to be proportional to connection pool size.
92- //
93- // Default: max(1, PoolSize/50)
94- MinWorkers int
95-
9689 // MaxWorkers is the maximum number of worker goroutines for processing handoff requests.
97- // The processor will scale up to this number when under load.
98- // If zero, defaults to max(MinWorkers*4, PoolSize/10) to handle bursts effectively.
90+ // Workers are created on-demand and automatically cleaned up when idle.
91+ // If zero, defaults to min(10, PoolSize/3) to handle bursts effectively.
92+ // If explicitly set, enforces minimum of 10 workers.
9993 //
100- // Default: max(MinWorkers*4 , PoolSize/10)
94+ // Default: min(10 , PoolSize/3), Minimum when set: 10
10195 MaxWorkers int
10296
10397 // HandoffQueueSize is the size of the buffered channel used to queue handoff requests.
10498 // If the queue is full, new handoff requests will be rejected.
99+ // Always capped by pool size since you can't handoff more connections than exist.
105100 //
106- // Default: 10x max workers, but never more than pool size, min 2
101+ // Default: 10x max workers, capped by pool size, min 2
107102 HandoffQueueSize int
108103
109104 // PostHandoffRelaxedDuration is how long to keep relaxed timeouts on the new connection
@@ -198,7 +193,6 @@ func DefaultConfig() *Config {
198193 EndpointType : EndpointTypeAuto , // Auto-detect based on connection
199194 RelaxedTimeout : 30 * time .Second ,
200195 HandoffTimeout : 15 * time .Second ,
201- MinWorkers : 0 , // Auto-calculated based on pool size
202196 MaxWorkers : 0 , // Auto-calculated based on pool size
203197 HandoffQueueSize : 0 , // Auto-calculated based on max workers
204198 PostHandoffRelaxedDuration : 0 , // Auto-calculated based on relaxed timeout
@@ -239,12 +233,9 @@ func (c *Config) Validate() error {
239233 }
240234 // Validate worker configuration
241235 // Allow 0 for auto-calculation, but negative values are invalid
242- if c .MinWorkers < 0 {
236+ if c .MaxWorkers < 0 {
243237 return ErrInvalidHandoffWorkers
244238 }
245- if c .MinWorkers > 0 && c .MaxWorkers > 0 && c .MaxWorkers < c .MinWorkers {
246- return ErrInvalidWorkerRange
247- }
248239 // HandoffQueueSize validation - allow 0 for auto-calculation
249240 if c .HandoffQueueSize < 0 {
250241 return ErrInvalidHandoffQueueSize
@@ -369,7 +360,6 @@ func (c *Config) ApplyDefaultsWithPoolSize(poolSize int) *Config {
369360 }
370361
371362 // Copy worker configuration
372- result .MinWorkers = c .MinWorkers
373363 result .MaxWorkers = c .MaxWorkers
374364
375365 // Apply worker defaults based on pool size
@@ -383,6 +373,10 @@ func (c *Config) ApplyDefaultsWithPoolSize(poolSize int) *Config {
383373 } else {
384374 result .HandoffQueueSize = c .HandoffQueueSize
385375 }
376+
377+ // Always cap queue size by pool size - no point having more queue slots than connections
378+ result .HandoffQueueSize = util .Min (result .HandoffQueueSize , poolSize )
379+
386380 // Ensure minimum queue size of 2
387381 if result .HandoffQueueSize < 2 {
388382 result .HandoffQueueSize = 2
@@ -491,7 +485,6 @@ func (c *Config) Clone() *Config {
491485 EndpointType : c .EndpointType ,
492486 RelaxedTimeout : c .RelaxedTimeout ,
493487 HandoffTimeout : c .HandoffTimeout ,
494- MinWorkers : c .MinWorkers ,
495488 MaxWorkers : c .MaxWorkers ,
496489 HandoffQueueSize : c .HandoffQueueSize ,
497490 PostHandoffRelaxedDuration : c .PostHandoffRelaxedDuration ,
@@ -521,19 +514,17 @@ func (c *Config) applyWorkerDefaults(poolSize int) {
521514 poolSize = 10 * runtime .GOMAXPROCS (0 )
522515 }
523516
524- // MinWorkers: max(1, poolSize/50) - conservative baseline
525- if c .MinWorkers == 0 {
526- c .MinWorkers = util .Max (1 , poolSize / 50 )
527- }
528-
529- // MaxWorkers: max(MinWorkers*4, poolSize/10) - handle bursts effectively
530517 if c .MaxWorkers == 0 {
531- c .MaxWorkers = util .Max (c .MinWorkers * 4 , poolSize / 10 )
518+ // When not set: min(10, poolSize/3) - don't exceed 10 workers for small pools
519+ c .MaxWorkers = util .Min (10 , poolSize / 3 )
520+ } else {
521+ // When explicitly set: max(10, set_value) - ensure at least 10 workers
522+ c .MaxWorkers = util .Max (10 , c .MaxWorkers )
532523 }
533524
534- // Ensure MaxWorkers >= MinWorkers
535- if c .MaxWorkers < c . MinWorkers {
536- c .MaxWorkers = c . MinWorkers
525+ // Ensure minimum of 1 worker (fallback for very small pools)
526+ if c .MaxWorkers < 1 {
527+ c .MaxWorkers = 1
537528 }
538529}
539530
0 commit comments