diff options
author | Igor Wiedler <iwiedler@gitlab.com> | 2021-03-12 14:42:08 +0300 |
---|---|---|
committer | Igor Wiedler <iwiedler@gitlab.com> | 2021-03-16 13:05:19 +0300 |
commit | f5df24b6578aded39f69107a768925b6d34e3ebd (patch) | |
tree | 992f9cb25ed7a269eeec077ac8a3b8c22411f8e6 | |
parent | b2bebb9733332031654f203a42c9912831d49a15 (diff) |
Pass metrics into limiter to better decouple the instrumentation
-rw-r--r-- | app.go | 7 | ||||
-rw-r--r-- | internal/netutil/shared_limit_listener.go | 33 | ||||
-rw-r--r-- | metrics/metrics.go | 4 |
3 files changed, 34 insertions, 10 deletions
@@ -361,7 +361,12 @@ func (a *theApp) Run() { var limiter *netutil.Limiter if a.config.General.MaxConns > 0 { - limiter = netutil.NewLimiter(a.config.General.MaxConns) + limiter = netutil.NewLimiterWithMetrics( + a.config.General.MaxConns, + metrics.LimitListenerMaxConns, + metrics.LimitListenerConcurrentConns, + metrics.LimitListenerWaitingConns, + ) } // Use a common pipeline to use a single instance of each handler, diff --git a/internal/netutil/shared_limit_listener.go b/internal/netutil/shared_limit_listener.go index 7d36e36f..05bf401e 100644 --- a/internal/netutil/shared_limit_listener.go +++ b/internal/netutil/shared_limit_listener.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "gitlab.com/gitlab-org/gitlab-pages/metrics" + "github.com/prometheus/client_golang/prometheus" ) var ( @@ -27,17 +27,30 @@ func SharedLimitListener(listener net.Listener, limiter *Limiter) net.Listener { // Limiter is used to provide a shared pool of connection slots. Use NewLimiter // to create an instance type Limiter struct { - sem chan struct{} + sem chan struct{} + concurrentConnsCount prometheus.Gauge + waitingConnsCount prometheus.Gauge + lock sync.Mutex } // NewLimiter creates a Limiter with the given capacity func NewLimiter(n int) *Limiter { - metrics.LimitListenerMaxConns.Set(float64(n)) return &Limiter{ sem: make(chan struct{}, n), } } +// NewLimiterWithMetrics creates a Limiter with metrics +func NewLimiterWithMetrics(n int, maxConnsCount, concurrentConnsCount, waitingConnsCount prometheus.Gauge) *Limiter { + maxConnsCount.Set(float64(n)) + + return &Limiter{ + sem: make(chan struct{}, n), + concurrentConnsCount: concurrentConnsCount, + waitingConnsCount: waitingConnsCount, + } +} + type sharedLimitListener struct { net.Listener closeOnce sync.Once // ensures the done chan is only closed once @@ -49,20 +62,26 @@ type sharedLimitListener struct { // accquired, false if the listener is closed and the semaphore is not // acquired. func (l *sharedLimitListener) acquire() bool { - metrics.LimitListenerWaiting.Inc() - defer metrics.LimitListenerWaiting.Dec() + if l.limiter.waitingConnsCount != nil { + l.limiter.waitingConnsCount.Inc() + defer l.limiter.waitingConnsCount.Dec() + } select { case <-l.done: return false case l.limiter.sem <- struct{}{}: - metrics.LimitListenerConcurrentConns.Inc() + if l.limiter.concurrentConnsCount != nil { + l.limiter.concurrentConnsCount.Inc() + } return true } } func (l *sharedLimitListener) release() { <-l.limiter.sem - metrics.LimitListenerConcurrentConns.Dec() + if l.limiter.concurrentConnsCount != nil { + l.limiter.concurrentConnsCount.Dec() + } } func (l *sharedLimitListener) Accept() (net.Conn, error) { diff --git a/metrics/metrics.go b/metrics/metrics.go index b17e8946..f4e27f9b 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -221,7 +221,7 @@ var ( }, ) - LimitListenerWaiting = prometheus.NewGauge( + LimitListenerWaitingConns = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "gitlab_pages_limit_listener_waiting_conns", Help: "The number of backlogged connections waiting on concurrency limit.", @@ -260,6 +260,6 @@ func MustRegister() { RejectedRequestsCount, LimitListenerMaxConns, LimitListenerConcurrentConns, - LimitListenerWaiting, + LimitListenerWaitingConns, ) } |