mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-29 13:26:00 +03:00
Replaced cpu directive with command line flag
This commit is contained in:
parent
27fc1672d4
commit
aa89b95075
4 changed files with 49 additions and 59 deletions
|
@ -47,9 +47,6 @@ type Config struct {
|
||||||
// these are executed in response to SIGINT and are blocking
|
// these are executed in response to SIGINT and are blocking
|
||||||
Shutdown []func() error
|
Shutdown []func() error
|
||||||
|
|
||||||
// MaxCPU is the maximum number of cores for the whole process to use
|
|
||||||
MaxCPU int
|
|
||||||
|
|
||||||
// The path to the configuration file from which this was loaded
|
// The path to the configuration file from which this was loaded
|
||||||
ConfigFile string
|
ConfigFile string
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,6 @@ package config
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/mholt/caddy/middleware"
|
"github.com/mholt/caddy/middleware"
|
||||||
)
|
)
|
||||||
|
@ -74,46 +71,6 @@ func init() {
|
||||||
p.cfg.TLS = tls
|
p.cfg.TLS = tls
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
"cpu": func(p *parser) error {
|
|
||||||
sysCores := runtime.NumCPU()
|
|
||||||
|
|
||||||
if !p.nextArg() {
|
|
||||||
return p.argErr()
|
|
||||||
}
|
|
||||||
strNum := p.tkn()
|
|
||||||
|
|
||||||
setCPU := func(val int) {
|
|
||||||
if val < 1 {
|
|
||||||
val = 1
|
|
||||||
}
|
|
||||||
if val > sysCores {
|
|
||||||
val = sysCores
|
|
||||||
}
|
|
||||||
if val > p.cfg.MaxCPU {
|
|
||||||
p.cfg.MaxCPU = val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasSuffix(strNum, "%") {
|
|
||||||
// Percent
|
|
||||||
var percent float32
|
|
||||||
pctStr := strNum[:len(strNum)-1]
|
|
||||||
pctInt, err := strconv.Atoi(pctStr)
|
|
||||||
if err != nil || pctInt < 1 || pctInt > 100 {
|
|
||||||
return p.err("Parse", "Invalid number '"+strNum+"' (must be a positive percentage between 1 and 100)")
|
|
||||||
}
|
|
||||||
percent = float32(pctInt) / 100
|
|
||||||
setCPU(int(float32(sysCores) * percent))
|
|
||||||
} else {
|
|
||||||
// Number
|
|
||||||
num, err := strconv.Atoi(strNum)
|
|
||||||
if err != nil || num < 0 {
|
|
||||||
return p.err("Parse", "Invalid number '"+strNum+"' (requires positive integer or percent)")
|
|
||||||
}
|
|
||||||
setCPU(num)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
"startup": func(p *parser) error {
|
"startup": func(p *parser) error {
|
||||||
// TODO: This code is duplicated with the shutdown directive below
|
// TODO: This code is duplicated with the shutdown directive below
|
||||||
|
|
||||||
|
|
47
main.go
47
main.go
|
@ -1,10 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/mholt/caddy/config"
|
"github.com/mholt/caddy/config"
|
||||||
|
@ -15,18 +19,26 @@ var (
|
||||||
conf string
|
conf string
|
||||||
http2 bool // TODO: temporary flag until http2 is standard
|
http2 bool // TODO: temporary flag until http2 is standard
|
||||||
quiet bool
|
quiet bool
|
||||||
|
cpu string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&conf, "conf", config.DefaultConfigFile, "the configuration file to use")
|
flag.StringVar(&conf, "conf", config.DefaultConfigFile, "the configuration file to use")
|
||||||
flag.BoolVar(&http2, "http2", true, "enable HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
|
flag.BoolVar(&http2, "http2", true, "enable HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
|
||||||
flag.BoolVar(&quiet, "quiet", false, "quiet mode (no initialization output)")
|
flag.BoolVar(&quiet, "quiet", false, "quiet mode (no initialization output)")
|
||||||
|
flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
// Set CPU cap
|
||||||
|
err := setCPU(cpu)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Load config from file
|
// Load config from file
|
||||||
allConfigs, err := config.Load(conf)
|
allConfigs, err := config.Load(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,3 +121,38 @@ func arrangeBindings(allConfigs []config.Config) (map[string][]config.Config, er
|
||||||
|
|
||||||
return addresses, nil
|
return addresses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setCPU parses string cpu and sets GOMAXPROCS
|
||||||
|
// according to its value. It accepts either
|
||||||
|
// a number (e.g. 3) or a percent (e.g. 50%).
|
||||||
|
func setCPU(cpu string) error {
|
||||||
|
var numCPU int
|
||||||
|
|
||||||
|
availCPU := runtime.NumCPU()
|
||||||
|
|
||||||
|
if strings.HasSuffix(cpu, "%") {
|
||||||
|
// Percent
|
||||||
|
var percent float32
|
||||||
|
pctStr := cpu[:len(cpu)-1]
|
||||||
|
pctInt, err := strconv.Atoi(pctStr)
|
||||||
|
if err != nil || pctInt < 1 || pctInt > 100 {
|
||||||
|
return errors.New("Invalid CPU value: percentage must be between 1-100")
|
||||||
|
}
|
||||||
|
percent = float32(pctInt) / 100
|
||||||
|
numCPU = int(float32(availCPU) * percent)
|
||||||
|
} else {
|
||||||
|
// Number
|
||||||
|
num, err := strconv.Atoi(cpu)
|
||||||
|
if err != nil || num < 1 {
|
||||||
|
return errors.New("Invalid CPU value: provide a number or percent greater than 0")
|
||||||
|
}
|
||||||
|
numCPU = num
|
||||||
|
}
|
||||||
|
|
||||||
|
if numCPU > availCPU {
|
||||||
|
numCPU = availCPU
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.GOMAXPROCS(numCPU)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/bradfitz/http2"
|
"github.com/bradfitz/http2"
|
||||||
"github.com/mholt/caddy/config"
|
"github.com/mholt/caddy/config"
|
||||||
|
@ -41,11 +40,6 @@ func New(addr string, configs []config.Config, tls bool) (*Server, error) {
|
||||||
return nil, fmt.Errorf("Cannot serve %s - host already defined for address %s", conf.Address(), s.address)
|
return nil, fmt.Errorf("Cannot serve %s - host already defined for address %s", conf.Address(), s.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use all CPUs (if needed) by default
|
|
||||||
if conf.MaxCPU == 0 {
|
|
||||||
conf.MaxCPU = runtime.NumCPU()
|
|
||||||
}
|
|
||||||
|
|
||||||
vh := virtualHost{config: conf}
|
vh := virtualHost{config: conf}
|
||||||
|
|
||||||
// Build middleware stack
|
// Build middleware stack
|
||||||
|
@ -73,7 +67,7 @@ func (s *Server) Serve() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, vh := range s.vhosts {
|
for _, vh := range s.vhosts {
|
||||||
// Execute startup functions
|
// Execute startup functions now
|
||||||
for _, start := range vh.config.Startup {
|
for _, start := range vh.config.Startup {
|
||||||
err := start()
|
err := start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -81,13 +75,8 @@ func (s *Server) Serve() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use highest procs value across all configurations
|
|
||||||
if vh.config.MaxCPU > 0 && vh.config.MaxCPU > runtime.GOMAXPROCS(0) {
|
|
||||||
runtime.GOMAXPROCS(vh.config.MaxCPU)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(vh.config.Shutdown) > 0 {
|
|
||||||
// Execute shutdown commands on exit
|
// Execute shutdown commands on exit
|
||||||
|
if len(vh.config.Shutdown) > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
interrupt := make(chan os.Signal, 1)
|
interrupt := make(chan os.Signal, 1)
|
||||||
signal.Notify(interrupt, os.Interrupt, os.Kill) // TODO: syscall.SIGQUIT? (Ctrl+\, Unix-only)
|
signal.Notify(interrupt, os.Interrupt, os.Kill) // TODO: syscall.SIGQUIT? (Ctrl+\, Unix-only)
|
||||||
|
|
Loading…
Reference in a new issue