Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Wiedler <iwiedler@gitlab.com>2021-03-12 14:42:08 +0300
committerIgor Wiedler <iwiedler@gitlab.com>2021-03-16 13:05:19 +0300
commitf5df24b6578aded39f69107a768925b6d34e3ebd (patch)
tree992f9cb25ed7a269eeec077ac8a3b8c22411f8e6
parentb2bebb9733332031654f203a42c9912831d49a15 (diff)
Pass metrics into limiter to better decouple the instrumentation
-rw-r--r--app.go7
-rw-r--r--internal/netutil/shared_limit_listener.go33
-rw-r--r--metrics/metrics.go4
3 files changed, 34 insertions, 10 deletions
diff --git a/app.go b/app.go
index 3df55b3e..c5555fc0 100644
--- a/app.go
+++ b/app.go
@@ -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,
)
}