Commit aa89b950 authored by Matthew Holt's avatar Matthew Holt

Replaced cpu directive with command line flag

parent 27fc1672
......@@ -47,9 +47,6 @@ type Config struct {
// these are executed in response to SIGINT and are blocking
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
ConfigFile string
}
......
......@@ -3,9 +3,6 @@ package config
import (
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"github.com/mholt/caddy/middleware"
)
......@@ -74,46 +71,6 @@ func init() {
p.cfg.TLS = tls
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 {
// TODO: This code is duplicated with the shutdown directive below
......
package main
import (
"errors"
"flag"
"fmt"
"log"
"net"
"runtime"
"strconv"
"strings"
"sync"
"github.com/mholt/caddy/config"
......@@ -15,18 +19,26 @@ var (
conf string
http2 bool // TODO: temporary flag until http2 is standard
quiet bool
cpu string
)
func init() {
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(&quiet, "quiet", false, "quiet mode (no initialization output)")
flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
flag.Parse()
}
func main() {
var wg sync.WaitGroup
// Set CPU cap
err := setCPU(cpu)
if err != nil {
log.Fatal(err)
}
// Load config from file
allConfigs, err := config.Load(conf)
if err != nil {
......@@ -109,3 +121,38 @@ func arrangeBindings(allConfigs []config.Config) (map[string][]config.Config, er
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"
"os"
"os/signal"
"runtime"
"github.com/bradfitz/http2"
"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)
}
// Use all CPUs (if needed) by default
if conf.MaxCPU == 0 {
conf.MaxCPU = runtime.NumCPU()
}
vh := virtualHost{config: conf}
// Build middleware stack
......@@ -73,7 +67,7 @@ func (s *Server) Serve() error {
}
for _, vh := range s.vhosts {
// Execute startup functions
// Execute startup functions now
for _, start := range vh.config.Startup {
err := start()
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
if len(vh.config.Shutdown) > 0 {
go func() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, os.Kill) // TODO: syscall.SIGQUIT? (Ctrl+\, Unix-only)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment