mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-15 00:50:25 +02:00
all: add configuration to limit max concurrent requests
Currently, there's no upper bound for how many requests that ctrld will handle at a time. This could be problem on some low capacity routers, where CPU/RAM is very limited. This commit adds a configuration to limit how many requests that will be handled concurrently. The default is 256, which should works well for most routers (the default concurrent requests of dnsmasq is 150).
This commit is contained in:
committed by
Cuong Manh Le
parent
d5e6c7b13f
commit
41139b3343
@@ -47,6 +47,8 @@ func (p *prog) serveDNS(listenerNum string) error {
|
||||
failoverRcodes = listenerConfig.Policy.FailoverRcodeNumbers
|
||||
}
|
||||
handler := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
|
||||
p.sema.acquire()
|
||||
defer p.sema.release()
|
||||
q := m.Question[0]
|
||||
domain := canonicalName(q.Name)
|
||||
reqId := requestID()
|
||||
@@ -60,7 +62,6 @@ func (p *prog) serveDNS(listenerNum string) error {
|
||||
if !matched && listenerConfig.Restricted {
|
||||
answer = new(dns.Msg)
|
||||
answer.SetRcode(m, dns.RcodeRefused)
|
||||
|
||||
} else {
|
||||
answer = p.proxy(ctx, upstreams, failoverRcodes, m)
|
||||
rtt := time.Since(t)
|
||||
|
||||
@@ -17,6 +17,8 @@ import (
|
||||
"github.com/Control-D-Inc/ctrld/internal/router"
|
||||
)
|
||||
|
||||
const defaultSemaphoreCap = 256
|
||||
|
||||
var logf = func(format string, args ...any) {
|
||||
mainLog.Debug().Msgf(format, args...)
|
||||
}
|
||||
@@ -36,6 +38,7 @@ type prog struct {
|
||||
|
||||
cfg *ctrld.Config
|
||||
cache dnscache.Cacher
|
||||
sema semaphore
|
||||
}
|
||||
|
||||
func (p *prog) Start(s service.Service) error {
|
||||
@@ -56,6 +59,15 @@ func (p *prog) run() {
|
||||
p.cache = cacher
|
||||
}
|
||||
}
|
||||
p.sema = &chanSemaphore{ready: make(chan struct{}, defaultSemaphoreCap)}
|
||||
if mcr := p.cfg.Service.MaxConcurrentRequests; mcr != nil {
|
||||
n := *mcr
|
||||
if n == 0 {
|
||||
p.sema = &noopSemaphore{}
|
||||
} else {
|
||||
p.sema = &chanSemaphore{ready: make(chan struct{}, n)}
|
||||
}
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(p.cfg.Listener))
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
type semaphore interface {
|
||||
acquire()
|
||||
release()
|
||||
}
|
||||
|
||||
type noopSemaphore struct{}
|
||||
|
||||
func (n noopSemaphore) acquire() {}
|
||||
|
||||
func (n noopSemaphore) release() {}
|
||||
|
||||
type chanSemaphore struct {
|
||||
ready chan struct{}
|
||||
}
|
||||
|
||||
func (c *chanSemaphore) acquire() {
|
||||
c.ready <- struct{}{}
|
||||
}
|
||||
|
||||
func (c *chanSemaphore) release() {
|
||||
<-c.ready
|
||||
}
|
||||
Reference in New Issue
Block a user