From: Urban Wallasch Date: Wed, 10 Apr 2019 21:04:16 +0000 (+0200) Subject: * Added options to set connection and worker queue limits. X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;h=171dae88b5722fb868dc3f389a0bed15ff2ed43c;p=gogopherd.git * Added options to set connection and worker queue limits. * Improved usage strings of several flags. --- diff --git a/README.md b/README.md index b1de47d..c078f28 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,18 @@ options: -i string interface to bind to; empty for any (default "localhost") + -lb int + set connection burst limit (default 50) + + -lc int + set connections per second rate limit (default 5) + + -lj int + set worker job queue size (default 50) + + -lw int + set number of worker threads (default 6) + -p string TCP port to listen on (default "7070") diff --git a/config.go b/config.go index 129ee8a..6e5ea1d 100644 --- a/config.go +++ b/config.go @@ -32,6 +32,10 @@ var cfg = struct { showdot bool indexes bool timeout int + crate int + cburst int + njobs int + nworker int logfile string verbose bool }{ @@ -46,6 +50,10 @@ var cfg = struct { showdot: false, indexes: false, timeout: 60, + crate: 5, + cburst: 50, + nworker: 6, + njobs: 50, logfile: "", verbose: false, } @@ -89,6 +97,14 @@ func parseConfigFile(filename string) error { cfg.indexes = strToBool(val) case "timeout": cfg.timeout, _ = strconv.Atoi(val) + case "crate": + cfg.crate, _ = strconv.Atoi(val) + case "cburst": + cfg.cburst, _ = strconv.Atoi(val) + case "nworker": + cfg.nworker, _ = strconv.Atoi(val) + case "njobs": + cfg.njobs, _ = strconv.Atoi(val) case "logfile": cfg.logfile = val case "verbose": @@ -104,20 +120,24 @@ func initialize() { var err error help := false cfgfile := "" - flag.StringVar(&cfgfile, "c", cfgfile, "configuration file") + flag.StringVar(&cfgfile, "c", cfgfile, "read configuration from `file`") flag.StringVar(&cfg.iface, "i", cfg.iface, "interface to bind to; empty for any") - flag.StringVar(&cfg.port, "p", cfg.port, "TCP port to listen on") + flag.StringVar(&cfg.port, "p", cfg.port, "TCP `port` to listen on") flag.StringVar(&cfg.fqdn, "f", cfg.fqdn, "fully qualified domain name") - flag.StringVar(&cfg.docroot, "r", cfg.docroot, "document root directory") - flag.StringVar(&cfg.idxpage, "I", cfg.idxpage, "directory index page") - flag.StringVar(&cfg.header, "H", cfg.header, "header file to prepend to generated pages") - flag.StringVar(&cfg.footer, "F", cfg.footer, "footer file to append to generated pages") - flag.BoolVar(&help, "h", help, "show this help page") + flag.StringVar(&cfg.docroot, "r", cfg.docroot, "document root `directory`") + flag.StringVar(&cfg.idxpage, "I", cfg.idxpage, "directory index `file` name") + flag.StringVar(&cfg.header, "H", cfg.header, "header: prepend contents of `file` to generated pages") + flag.StringVar(&cfg.footer, "F", cfg.footer, "footer: append contents of `file` to generated pages") + flag.BoolVar(&help, "h", help, "display this help message") flag.BoolVar(&cfg.fsymln, "s", cfg.fsymln, "follow symbolic links") flag.BoolVar(&cfg.showdot, "d", cfg.showdot, "allow access to dotfiles") flag.BoolVar(&cfg.indexes, "D", cfg.indexes, "allow generated directory indexes") - flag.IntVar(&cfg.timeout, "t", cfg.timeout, "connection read/write timeout in seconds") - flag.StringVar(&cfg.logfile, "L", cfg.logfile, "write log to file; empty for stderr") + flag.IntVar(&cfg.timeout, "t", cfg.timeout, "connection read/write timeout in `seconds`") + flag.IntVar(&cfg.crate, "lc", cfg.crate, "set connections per second rate limit to `num`") + flag.IntVar(&cfg.cburst, "lb", cfg.cburst, "set connection burst limit to `num`") + flag.IntVar(&cfg.nworker, "lw", cfg.nworker, "set number of worker threads to `num`") + flag.IntVar(&cfg.njobs, "lj", cfg.njobs, "set worker job queue size to `num`") + flag.StringVar(&cfg.logfile, "L", cfg.logfile, "write log to `file`; empty for stderr") flag.BoolVar(&cfg.verbose, "v", cfg.verbose, "produce verbose output") flag.Parse() if help { @@ -163,6 +183,10 @@ func initialize() { tracer.Print("showdot: ", cfg.showdot) tracer.Print("indexes: ", cfg.indexes) tracer.Print("timeout: ", cfg.timeout) + tracer.Print("crate: ", cfg.crate) + tracer.Print("cburst: ", cfg.cburst) + tracer.Print("nworker: ", cfg.nworker) + tracer.Print("njobs: ", cfg.njobs) tracer.Print("verbose: ", cfg.verbose) tracer.Print("gogopherd version ", version) } diff --git a/gogopherd.cfg.example b/gogopherd.cfg.example index 64710ac..8dfa9a8 100644 --- a/gogopherd.cfg.example +++ b/gogopherd.cfg.example @@ -26,6 +26,14 @@ indexes = true # Connection read and write timeout in seconds timeout = 60 +# Connections per second rate limit +crate = 5 +# Connection burst limit +cburst = 50 +# Number of worker threads +nworker = 6 +# Worker job queue size +njobs = 50 # Log to file; leave empty for stderr logfile = "" diff --git a/gogopherd.go b/gogopherd.go index 0b029db..8b8b577 100644 --- a/gogopherd.go +++ b/gogopherd.go @@ -249,12 +249,9 @@ func handleRequest(conn net.Conn) { func serveTCP(listener *net.TCPListener) { // connection rate limiter - rate := 5 - burst := 50 - interval := time.Second / time.Duration(rate) - tick := time.NewTicker(interval) + tick := time.NewTicker(time.Second / time.Duration(cfg.crate)) defer tick.Stop() - throttle := make(chan time.Time, burst) + throttle := make(chan time.Time, cfg.cburst) go func() { for t := range tick.C { select { @@ -264,10 +261,8 @@ func serveTCP(listener *net.TCPListener) { } }() // worker and job queue setup - nworker := 5 - njobs := 50 - jobs := make(chan net.Conn, njobs) - for w := 1; w <= nworker; w++ { + jobs := make(chan net.Conn, cfg.njobs) + for w := 1; w <= cfg.nworker; w++ { go func(id int, jobs <-chan net.Conn) { for j := range jobs { tracer.Print("worker id ", id, ": ", j.RemoteAddr())