Skip to content

Commit 67b6c2f

Browse files
authored
Merge pull request #71 from thushan/feature/october-2025-updates
fixes: October 2025 performance improvements
2 parents 8ad09fd + 837dc42 commit 67b6c2f

23 files changed

+2134
-130
lines changed

internal/adapter/balancer/factory_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,15 @@ func createTestEndpoints(count int, status domain.EndpointStatus) []*domain.Endp
278278
testURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", port))
279279
healthURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d/health", port))
280280
endpoints[i] = &domain.Endpoint{
281-
Name: fmt.Sprintf("endpoint-%d", i),
282-
URL: testURL,
283-
HealthCheckURL: healthURL,
284-
Status: status,
285-
Priority: 100 + i,
286-
CheckInterval: 5 * time.Second,
287-
CheckTimeout: 2 * time.Second,
281+
Name: fmt.Sprintf("endpoint-%d", i),
282+
URL: testURL,
283+
URLString: testURL.String(),
284+
HealthCheckURL: healthURL,
285+
HealthCheckURLString: healthURL.String(),
286+
Status: status,
287+
Priority: 100 + i,
288+
CheckInterval: 5 * time.Second,
289+
CheckTimeout: 2 * time.Second,
288290
}
289291
}
290292
return endpoints

internal/adapter/balancer/least_connection_test.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,10 @@ func TestLeastConnectionsSelector_DifferentURLFormats(t *testing.T) {
347347
t.Run(tc.name, func(t *testing.T) {
348348
testURL, _ := url.Parse(tc.url)
349349
endpoint := &domain.Endpoint{
350-
Name: tc.name,
351-
URL: testURL,
352-
Status: domain.StatusHealthy,
350+
Name: tc.name,
351+
URL: testURL,
352+
URLString: testURL.String(),
353+
Status: domain.StatusHealthy,
353354
}
354355

355356
// Test connection tracking with different URL formats
@@ -375,12 +376,14 @@ func createTestEndpoint(name string, port int, status domain.EndpointStatus) *do
375376
testURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", port))
376377
healthURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d/health", port))
377378
return &domain.Endpoint{
378-
Name: name,
379-
URL: testURL,
380-
HealthCheckURL: healthURL,
381-
Status: status,
382-
Priority: 100,
383-
CheckInterval: 5 * time.Second,
384-
CheckTimeout: 2 * time.Second,
379+
Name: name,
380+
URL: testURL,
381+
URLString: testURL.String(),
382+
HealthCheckURL: healthURL,
383+
HealthCheckURLString: healthURL.String(),
384+
Status: status,
385+
Priority: 100,
386+
CheckInterval: 5 * time.Second,
387+
CheckTimeout: 2 * time.Second,
385388
}
386389
}

internal/adapter/balancer/least_connections.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ func (l *LeastConnectionsSelector) Select(ctx context.Context, endpoints []*doma
4747
minConnections := int64(-1)
4848

4949
for _, endpoint := range routable {
50-
key := endpoint.URL.String()
51-
connections := connectionStats[key] // Will be 0 if not found
50+
connections := connectionStats[endpoint.URLString] // Will be 0 if not found
5251

5352
if minConnections == -1 || connections < minConnections {
5453
minConnections = connections

internal/adapter/balancer/priority_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,12 +513,14 @@ func createPriorityEndpoint(name string, port int, status domain.EndpointStatus,
513513
testURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", port))
514514
healthURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d/health", port))
515515
return &domain.Endpoint{
516-
Name: name,
517-
URL: testURL,
518-
HealthCheckURL: healthURL,
519-
Status: status,
520-
Priority: priority,
521-
CheckInterval: 5 * time.Second,
522-
CheckTimeout: 2 * time.Second,
516+
Name: name,
517+
URL: testURL,
518+
URLString: testURL.String(),
519+
HealthCheckURL: healthURL,
520+
HealthCheckURLString: healthURL.String(),
521+
Status: status,
522+
Priority: priority,
523+
CheckInterval: 5 * time.Second,
524+
CheckTimeout: 2 * time.Second,
523525
}
524526
}

internal/adapter/balancer/round_robin_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,14 @@ func createRoundRobinEndpoint(name string, port int, status domain.EndpointStatu
516516
testURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", port))
517517
healthURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d/health", port))
518518
return &domain.Endpoint{
519-
Name: name,
520-
URL: testURL,
521-
HealthCheckURL: healthURL,
522-
Status: status,
523-
Priority: 100,
524-
CheckInterval: 5 * time.Second,
525-
CheckTimeout: 2 * time.Second,
519+
Name: name,
520+
URL: testURL,
521+
URLString: testURL.String(),
522+
HealthCheckURL: healthURL,
523+
HealthCheckURLString: healthURL.String(),
524+
Status: status,
525+
Priority: 100,
526+
CheckInterval: 5 * time.Second,
527+
CheckTimeout: 2 * time.Second,
526528
}
527529
}

internal/adapter/health/circuit_breaker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type HTTPClient interface {
2020

2121
// CircuitBreaker tracks failure rates and prevents cascading failures
2222
// TODO: (HOT-RELOAD) Add cleanup mechanism for removed endpoints when hot reload is implemented
23-
// The endpoints xsync.MapOf will accumulate stale entries for removed/changed endpoints without TTL
23+
// The endpoints xsync.Map will accumulate stale entries for removed/changed endpoints without TTL
2424
type CircuitBreaker struct {
2525
endpoints *xsync.Map[string, *circuitState]
2626
failureThreshold int

internal/adapter/proxy/core/common.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"net"
55
"net/http"
66
"slices"
7+
"strconv"
78
"strings"
89
"time"
910

@@ -35,7 +36,10 @@ func GetViaHeader() string {
3536

3637
// CopyHeaders copies headers from originalReq to proxyReq with proper handling
3738
func CopyHeaders(proxyReq, originalReq *http.Request) {
38-
proxyReq.Header = make(http.Header)
39+
// Pre-size based on source to avoid rehashing
40+
if proxyReq.Header == nil {
41+
proxyReq.Header = make(http.Header, len(originalReq.Header))
42+
}
3943
for header, values := range originalReq.Header {
4044
// Skip hop-by-hop headers as per RFC 2616 section 13.5.1
4145
// these headers are connection-specific and shouldn't be forwarded
@@ -175,8 +179,8 @@ func SetResponseHeaders(w http.ResponseWriter, stats *ports.RequestStats, endpoi
175179

176180
// Calculate and set response time if we have timing information
177181
if !stats.StartTime.IsZero() {
178-
responseTime := time.Since(stats.StartTime)
179-
h.Set(constants.HeaderXOllaResponseTime, responseTime.String())
182+
responseTimeMs := time.Since(stats.StartTime).Milliseconds()
183+
h.Set(constants.HeaderXOllaResponseTime, strconv.FormatInt(responseTimeMs, 10)+"ms")
180184
}
181185

182186
// set routing decision headers if available

0 commit comments

Comments
 (0)