| 155 | } |
| 156 | |
| 157 | func calculateMaxThreads(opt *opt) (numWorkers int, _ error) { |
| 158 | maxProcs := runtime.GOMAXPROCS(0) * 2 |
| 159 | maxThreadsFromWorkers := 0 |
| 160 | |
| 161 | for i, w := range opt.workers { |
| 162 | if w.num <= 0 { |
| 163 | // https://github.com/php/frankenphp/issues/126 |
| 164 | opt.workers[i].num = maxProcs |
| 165 | } |
| 166 | metrics.TotalWorkers(w.name, w.num) |
| 167 | |
| 168 | numWorkers += opt.workers[i].num |
| 169 | |
| 170 | if w.maxThreads > 0 { |
| 171 | if w.maxThreads < w.num { |
| 172 | return 0, fmt.Errorf("worker max_threads (%d) must be greater or equal to worker num (%d) (%q)", w.maxThreads, w.num, w.fileName) |
| 173 | } |
| 174 | |
| 175 | if w.maxThreads > opt.maxThreads && opt.maxThreads > 0 { |
| 176 | return 0, fmt.Errorf("worker max_threads (%d) cannot be greater than total max_threads (%d) (%q)", w.maxThreads, opt.maxThreads, w.fileName) |
| 177 | } |
| 178 | |
| 179 | maxThreadsFromWorkers += w.maxThreads - w.num |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | numThreadsIsSet := opt.numThreads > 0 |
| 184 | maxThreadsIsSet := opt.maxThreads != 0 |
| 185 | maxThreadsIsAuto := opt.maxThreads < 0 // maxthreads < 0 signifies auto mode (see phpmaintread.go) |
| 186 | |
| 187 | // if max_threads is only defined in workers, scale up to the sum of all worker max_threads |
| 188 | if !maxThreadsIsSet && maxThreadsFromWorkers > 0 { |
| 189 | maxThreadsIsSet = true |
| 190 | if numThreadsIsSet { |
| 191 | opt.maxThreads = opt.numThreads + maxThreadsFromWorkers |
| 192 | } else { |
| 193 | opt.maxThreads = numWorkers + 1 + maxThreadsFromWorkers |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | if numThreadsIsSet && !maxThreadsIsSet { |
| 198 | opt.maxThreads = opt.numThreads |
| 199 | if opt.numThreads <= numWorkers { |
| 200 | return 0, fmt.Errorf("num_threads (%d) must be greater than the number of worker threads (%d)", opt.numThreads, numWorkers) |
| 201 | } |
| 202 | |
| 203 | return numWorkers, nil |
| 204 | } |
| 205 | |
| 206 | if maxThreadsIsSet && !numThreadsIsSet { |
| 207 | opt.numThreads = numWorkers + 1 |
| 208 | if !maxThreadsIsAuto && opt.numThreads > opt.maxThreads { |
| 209 | return 0, fmt.Errorf("max_threads (%d) must be greater than the number of worker threads (%d)", opt.maxThreads, numWorkers) |
| 210 | } |
| 211 | |
| 212 | return numWorkers, nil |
| 213 | } |
| 214 | |