generated from deploymenttheory/Template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
handler.go
73 lines (67 loc) · 3.44 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// concurrency/handler.go
package concurrency
import (
"sync"
"time"
"github.com/deploymenttheory/go-api-http-client/logger"
)
// ConcurrencyHandler controls the number of concurrent HTTP requests.
type ConcurrencyHandler struct {
sem chan struct{}
logger logger.Logger
AcquisitionTimes []time.Duration
lock sync.Mutex
lastTokenAcquisitionTime time.Time
Metrics *ConcurrencyMetrics
}
// ConcurrencyMetrics captures various metrics related to managing concurrency for the client's interactions with the API.
type ConcurrencyMetrics struct {
TotalRequests int64 // Total number of requests made
TotalRetries int64 // Total number of retry attempts
TotalRateLimitErrors int64 // Total number of rate limit errors encountered
PermitWaitTime time.Duration // Total time spent waiting for tokens
TTFB struct { // Metrics related to Time to First Byte (TTFB)
Total time.Duration // Total Time to First Byte (TTFB) for all requests
Count int64 // Count of requests used for calculating TTFB
Lock sync.Mutex // Lock for TTFB metrics
}
Throughput struct { // Metrics related to network throughput
Total float64 // Total network throughput for all requests
Count int64 // Count of requests used for calculating throughput
Lock sync.Mutex // Lock for throughput metrics/
}
ResponseTimeVariability struct { // Metrics related to response time variability
Total time.Duration // Total response time for all requests
Average time.Duration // Average response time across all requests
Variance float64 // Variance of response times
Count int64 // Count of responses used for calculating response time variability
Lock sync.Mutex // Lock for response time variability metrics
StdDevThreshold float64 // Maximum acceptable standard deviation for adjusting concurrency
DebounceScaleDownCount int // Counter to manage scale down actions after consecutive triggers
}
ResponseCodeMetrics struct {
ErrorRate float64 // Error rate calculated as (TotalRateLimitErrors + 5xxErrors) / TotalRequests
Lock sync.Mutex // Lock for response code metrics
}
Lock sync.Mutex // Lock for overall metrics fields
}
// NewConcurrencyHandler initializes a new ConcurrencyHandler with the given
// concurrency limit, logger, and concurrency metrics. The ConcurrencyHandler ensures
// no more than a certain number of concurrent requests are made.
// It uses a semaphore to control concurrency.
func NewConcurrencyHandler(limit int, logger logger.Logger, metrics *ConcurrencyMetrics) *ConcurrencyHandler {
return &ConcurrencyHandler{
sem: make(chan struct{}, limit),
logger: logger,
AcquisitionTimes: []time.Duration{},
Metrics: metrics,
}
}
// RequestIDKey is type used as a key for storing and retrieving
// request-specific identifiers from a context.Context object. This private
// type ensures that the key is distinct and prevents accidental value
// retrieval or conflicts with other context keys. The value associated
// with this key in a context is typically a UUID that uniquely identifies
// a request being processed by the ConcurrencyManager, allowing for
// fine-grained control and tracking of concurrent HTTP requests.
type RequestIDKey struct{}