|
57 | 57 | InvalidRequestError = errors.New("not a FrankenPHP request") |
58 | 58 | AlreadyStartedError = errors.New("FrankenPHP is already started") |
59 | 59 | InvalidPHPVersionError = errors.New("FrankenPHP is only compatible with PHP 8.2+") |
60 | | - NotEnoughThreads = errors.New("the number of threads must be superior to the number of workers") |
61 | 60 | MainThreadCreationError = errors.New("error creating the main thread") |
62 | 61 | RequestContextCreationError = errors.New("error during request context creation") |
63 | 62 | ScriptExecutionError = errors.New("error during PHP script execution") |
@@ -163,23 +162,52 @@ func calculateMaxThreads(opt *opt) (int, int, int, error) { |
163 | 162 | numWorkers += opt.workers[i].num |
164 | 163 | } |
165 | 164 |
|
166 | | - if opt.numThreads <= 0 { |
| 165 | + numThreadsIsSet := opt.numThreads > 0 |
| 166 | + maxThreadsIsSet := opt.maxThreads != 0 |
| 167 | + maxThreadsIsAuto := opt.maxThreads < 0 // maxthreads < 0 signifies auto mode (see phpmaintread.go) |
| 168 | + |
| 169 | + if numThreadsIsSet && !maxThreadsIsSet { |
| 170 | + opt.maxThreads = opt.numThreads |
| 171 | + if opt.numThreads <= numWorkers { |
| 172 | + err := fmt.Errorf("num_threads (%d) must be greater than the number of worker threads (%d)", opt.numThreads, numWorkers) |
| 173 | + return 0, 0, 0, err |
| 174 | + } |
| 175 | + |
| 176 | + return opt.numThreads, numWorkers, opt.maxThreads, nil |
| 177 | + } |
| 178 | + |
| 179 | + if maxThreadsIsSet && !numThreadsIsSet { |
| 180 | + opt.numThreads = numWorkers + 1 |
| 181 | + if !maxThreadsIsAuto && opt.numThreads > opt.maxThreads { |
| 182 | + err := fmt.Errorf("max_threads (%d) must be greater than the number of worker threads (%d)", opt.maxThreads, numWorkers) |
| 183 | + return 0, 0, 0, err |
| 184 | + } |
| 185 | + |
| 186 | + return opt.numThreads, numWorkers, opt.maxThreads, nil |
| 187 | + } |
| 188 | + |
| 189 | + if !numThreadsIsSet && !maxThreadsIsSet { |
167 | 190 | if numWorkers >= maxProcs { |
168 | 191 | // Start at least as many threads as workers, and keep a free thread to handle requests in non-worker mode |
169 | 192 | opt.numThreads = numWorkers + 1 |
170 | 193 | } else { |
171 | 194 | opt.numThreads = maxProcs |
172 | 195 | } |
173 | | - } else if opt.numThreads <= numWorkers { |
174 | | - return opt.numThreads, numWorkers, opt.maxThreads, NotEnoughThreads |
| 196 | + opt.maxThreads = opt.numThreads |
| 197 | + |
| 198 | + return opt.numThreads, numWorkers, opt.maxThreads, nil |
175 | 199 | } |
176 | 200 |
|
177 | | - if opt.maxThreads < opt.numThreads && opt.maxThreads > 0 { |
178 | | - opt.maxThreads = opt.numThreads |
| 201 | + // both num_threads and max_threads are set |
| 202 | + if opt.numThreads <= numWorkers { |
| 203 | + err := fmt.Errorf("num_threads (%d) must be greater than the number of worker threads (%d)", opt.numThreads, numWorkers) |
| 204 | + return 0, 0, 0, err |
179 | 205 | } |
180 | 206 |
|
181 | | - metrics.TotalThreads(opt.numThreads) |
182 | | - MaxThreads = opt.numThreads |
| 207 | + if !maxThreadsIsAuto && opt.maxThreads < opt.numThreads { |
| 208 | + err := fmt.Errorf("max_threads (%d) must be greater than or equal to num_threads (%d)", opt.maxThreads, opt.numThreads) |
| 209 | + return 0, 0, 0, err |
| 210 | + } |
183 | 211 |
|
184 | 212 | return opt.numThreads, numWorkers, opt.maxThreads, nil |
185 | 213 | } |
@@ -226,6 +254,9 @@ func Init(options ...Option) error { |
226 | 254 | return err |
227 | 255 | } |
228 | 256 |
|
| 257 | + metrics.TotalThreads(totalThreadCount) |
| 258 | + MaxThreads = totalThreadCount |
| 259 | + |
229 | 260 | config := Config() |
230 | 261 |
|
231 | 262 | if config.Version.MajorVersion < 8 || (config.Version.MajorVersion == 8 && config.Version.MinorVersion < 2) { |
|
0 commit comments