saving in place

This commit is contained in:
Krypto Kajun
2025-10-04 09:31:02 -05:00
parent 76c1b5cee1
commit f358f49aa9
295 changed files with 72071 additions and 17209 deletions

View File

@@ -36,14 +36,17 @@ type AdaptiveEndpoint struct {
}
// EndpointMetrics tracks performance metrics for an endpoint
// All fields must be 64-bit aligned for atomic access
type EndpointMetrics struct {
TotalRequests int64
SuccessfulRequests int64
FailedRequests int64
TotalLatency int64 // nanoseconds
LastRequestTime int64 // unix timestamp
SuccessRate float64
AverageLatency float64 // milliseconds
// Non-atomic fields - must be protected by mutex when accessed
mu sync.RWMutex
SuccessRate float64
AverageLatency float64 // milliseconds
}
// CircuitBreaker implements circuit breaker pattern for failed endpoints
@@ -86,8 +89,13 @@ func NewAdaptiveRateLimiter(cfg *config.ArbitrumConfig, logger *logger.Logger) *
// Create adaptive endpoint for primary endpoint
arl.addEndpoint(cfg.RPCEndpoint, cfg.RateLimit)
// Create adaptive endpoints for fallback endpoints
for _, endpoint := range cfg.FallbackEndpoints {
// Create adaptive endpoints for reading endpoints
for _, endpoint := range cfg.ReadingEndpoints {
arl.addEndpoint(endpoint.URL, endpoint.RateLimit)
}
// Create adaptive endpoints for execution endpoints
for _, endpoint := range cfg.ExecutionEndpoints {
arl.addEndpoint(endpoint.URL, endpoint.RateLimit)
}
@@ -231,6 +239,37 @@ func (arl *AdaptiveRateLimiter) getBestEndpoint() string {
return bestEndpoint
}
// updateDerivedMetrics safely updates calculated metrics with proper synchronization
func (em *EndpointMetrics) updateDerivedMetrics() {
totalRequests := atomic.LoadInt64(&em.TotalRequests)
successfulRequests := atomic.LoadInt64(&em.SuccessfulRequests)
totalLatency := atomic.LoadInt64(&em.TotalLatency)
em.mu.Lock()
defer em.mu.Unlock()
// Calculate success rate
if totalRequests > 0 {
em.SuccessRate = float64(successfulRequests) / float64(totalRequests)
} else {
em.SuccessRate = 0.0
}
// Calculate average latency in milliseconds
if totalRequests > 0 {
em.AverageLatency = float64(totalLatency) / float64(totalRequests) / 1e6 // ns to ms
} else {
em.AverageLatency = 0.0
}
}
// getCalculatedMetrics safely returns derived metrics
func (em *EndpointMetrics) getCalculatedMetrics() (float64, float64) {
em.mu.RLock()
defer em.mu.RUnlock()
return em.SuccessRate, em.AverageLatency
}
// calculateEndpointScore calculates a score for endpoint selection
func (arl *AdaptiveRateLimiter) calculateEndpointScore(endpoint *AdaptiveEndpoint) float64 {
// Base score on success rate (0-1)
@@ -238,13 +277,17 @@ func (arl *AdaptiveRateLimiter) calculateEndpointScore(endpoint *AdaptiveEndpoin
latencyWeight := 0.3
loadWeight := 0.1
successScore := endpoint.metrics.SuccessRate
// Update derived metrics first
endpoint.metrics.updateDerivedMetrics()
// Get calculated metrics safely
successScore, avgLatency := endpoint.metrics.getCalculatedMetrics()
// Invert latency score (lower latency = higher score)
latencyScore := 1.0
if endpoint.metrics.AverageLatency > 0 {
if avgLatency > 0 {
// Normalize latency score (assuming 1000ms is poor, 100ms is good)
latencyScore = 1.0 - (endpoint.metrics.AverageLatency / 1000.0)
latencyScore = 1.0 - (avgLatency / 1000.0)
if latencyScore < 0 {
latencyScore = 0
}

View File

@@ -36,8 +36,18 @@ func NewLimiterManager(cfg *config.ArbitrumConfig) *LimiterManager {
Config: cfg.RateLimit,
}
// Create limiters for fallback endpoints
for _, endpoint := range cfg.FallbackEndpoints {
// Create limiters for reading endpoints
for _, endpoint := range cfg.ReadingEndpoints {
limiter := createLimiter(endpoint.RateLimit)
lm.limiters[endpoint.URL] = &EndpointLimiter{
URL: endpoint.URL,
Limiter: limiter,
Config: endpoint.RateLimit,
}
}
// Create limiters for execution endpoints
for _, endpoint := range cfg.ExecutionEndpoints {
limiter := createLimiter(endpoint.RateLimit)
lm.limiters[endpoint.URL] = &EndpointLimiter{
URL: endpoint.URL,