fix: better max_threads calculation (#1446)

This commit is contained in:
Alexander Stecher
2025-03-19 13:21:10 +01:00
committed by GitHub
parent 93266dfcad
commit cc473ee03e
2 changed files with 84 additions and 9 deletions

View File

@@ -57,7 +57,6 @@ var (
InvalidRequestError = errors.New("not a FrankenPHP request")
AlreadyStartedError = errors.New("FrankenPHP is already started")
InvalidPHPVersionError = errors.New("FrankenPHP is only compatible with PHP 8.2+")
NotEnoughThreads = errors.New("the number of threads must be superior to the number of workers")
MainThreadCreationError = errors.New("error creating the main thread")
RequestContextCreationError = errors.New("error during request context creation")
ScriptExecutionError = errors.New("error during PHP script execution")
@@ -163,23 +162,52 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) {
numWorkers += opt.workers[i].num
}
if opt.numThreads <= 0 {
numThreadsIsSet := opt.numThreads > 0
maxThreadsIsSet := opt.maxThreads != 0
maxThreadsIsAuto := opt.maxThreads < 0 // maxthreads < 0 signifies auto mode (see phpmaintread.go)
if numThreadsIsSet && !maxThreadsIsSet {
opt.maxThreads = opt.numThreads
if opt.numThreads <= numWorkers {
err := fmt.Errorf("num_threads (%d) must be greater than the number of worker threads (%d)", opt.numThreads, numWorkers)
return 0, 0, 0, err
}
return opt.numThreads, numWorkers, opt.maxThreads, nil
}
if maxThreadsIsSet && !numThreadsIsSet {
opt.numThreads = numWorkers + 1
if !maxThreadsIsAuto && opt.numThreads > opt.maxThreads {
err := fmt.Errorf("max_threads (%d) must be greater than the number of worker threads (%d)", opt.maxThreads, numWorkers)
return 0, 0, 0, err
}
return opt.numThreads, numWorkers, opt.maxThreads, nil
}
if !numThreadsIsSet && !maxThreadsIsSet {
if numWorkers >= maxProcs {
// Start at least as many threads as workers, and keep a free thread to handle requests in non-worker mode
opt.numThreads = numWorkers + 1
} else {
opt.numThreads = maxProcs
}
} else if opt.numThreads <= numWorkers {
return opt.numThreads, numWorkers, opt.maxThreads, NotEnoughThreads
}
if opt.maxThreads < opt.numThreads && opt.maxThreads > 0 {
opt.maxThreads = opt.numThreads
return opt.numThreads, numWorkers, opt.maxThreads, nil
}
metrics.TotalThreads(opt.numThreads)
MaxThreads = opt.numThreads
// both num_threads and max_threads are set
if opt.numThreads <= numWorkers {
err := fmt.Errorf("num_threads (%d) must be greater than the number of worker threads (%d)", opt.numThreads, numWorkers)
return 0, 0, 0, err
}
if !maxThreadsIsAuto && opt.maxThreads < opt.numThreads {
err := fmt.Errorf("max_threads (%d) must be greater than or equal to num_threads (%d)", opt.maxThreads, opt.numThreads)
return 0, 0, 0, err
}
return opt.numThreads, numWorkers, opt.maxThreads, nil
}
@@ -226,6 +254,9 @@ func Init(options ...Option) error {
return err
}
metrics.TotalThreads(totalThreadCount)
MaxThreads = totalThreadCount
config := Config()
if config.Version.MajorVersion < 8 || (config.Version.MajorVersion == 8 && config.Version.MinorVersion < 2) {