You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: request_limiter.go
    path of file: ./repos/arvados/sdk/go/httpserver
    
    the code of the file until where you have to start completion: // Copyright (C) The Arvados Authors. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0

package httpserver

import (
	"container/heap"
	"math"
	"net/http"
	"sync"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/sirupsen/logrus"
)

const MinPriority = math.MinInt64

// Prometheus typically polls every 10 seconds, but it doesn't cost us
// much to also accommodate higher frequency collection by updating
// internal stats more frequently. (This limits time resolution only
// for the metrics that aren't generated on the fly.)
const metricsUpdateInterval = time.Second

// RequestLimiter wraps http.Handler, limiting the number of
// concurrent requests being handled by the wrapped Handler. Requests
// that arrive when the handler is already at the specified
// concurrency limit are queued and handled in the order indicated by
// the Priority function.
//
// Caller must not modify any RequestLimiter fields after calling its
// methods.
type RequestLimiter struct {
	Handler http.Handler

	// Queue determines which queue a request is assigned t
    
func (rl *RequestLimiter) setup() {
	if rl.Registry != nil {
		mCurrentReqs := prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: "arvados",
			Name:      "concurrent_requests",
			Help:      "Number of requests in progress",
		}, []string{"queue"})
		rl.Registry.MustRegister(mCurrentReqs)
		mMaxReqs := prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: "arvados",
			Name:      "max_concurrent_requests",
			Help:      "Maximum number of concurrent requests",
		}, []string{"queue"})
		rl.Registry.MustRegister(mMaxReqs)
		mMaxQueue := prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: "arvados",
			Name:      "max_queued_requests",
			Help:      "Maximum number of queued requests",
		}, []string{"queue"})
		rl.Registry.MustRegister(mMaxQueue)
		rl.mQueueUsage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: "arvados",
			Name:      "queued_requests",
			Help:      "Number of requests in queue",
		}, []string{"queue", "priority"})
		rl.Registry.MustRegister(rl.mQueueUsage)
		rl.mQueueDelay = prometheus.NewSummaryVec(prometheus.SummaryOpts{
			Namespace:  "arvados",
			Name:       "queue_delay_seconds",
			Help:       "Time spent in the incoming request queue before start of processing",
			Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.95: 0.005, 0.99: 0.001},
		}, []string{"queue", "priority"})
		rl.Registry.MustRegister(rl.mQueueDelay)
		rl.mQueueTimeout = prometheus.NewSummaryVec(prometheus.SummaryOpts{
			Namespace:  "arvados",
			Name:       "queue_timeout_seconds",
			Help:       "Time spent in the incoming request queue before client timed out or disconnected",
			Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.95: 0.005, 0.99: 0.001},
		}, []string{"queue", "priority"})
		rl.Registry.MustRegister(rl.mQueueTimeout)
		go func() {
			for range time.NewTicker(metricsUpdateInterval).C {
				rl.mtx.Lock()
				for rq := range rl.rqs {
					var low, normal, high int
					for _, ent := range rq.queue {
						switch {
						case ent.priority < 0:
							low++
						case ent.priority > 0:
							high++
						default:
							normal++
						}
					}
					mCurrentReqs.WithLabelValues(rq.Label).Set(float64(rq.handling))
					mMaxReqs.WithLabelValues(rq.Label).Set(float64(rq.MaxConcurrent))
					mMaxQueue.WithLabelValues(rq.Label).Set(float64(rq.MaxQueue))
					rl.mQueueUsage.WithLabelValues(rq.Label, "low").Set(float64(low))
					rl.mQueueUsage.WithLabelValues(rq.Label, "normal").Set(float64(normal))
					rl.mQueueUsage.WithLabelValues(rq.Label, "high").Set(float64(high))
				}
				rl.mtx.Unlock()
			}
		}()
	}
}