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 /internal/netutil | |
parent | b2bebb9733332031654f203a42c9912831d49a15 (diff) |
Pass metrics into limiter to better decouple the instrumentation
Diffstat (limited to 'internal/netutil')
-rw-r--r-- | internal/netutil/shared_limit_listener.go | 33 |
1 files changed, 26 insertions, 7 deletions
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) { |