fix: address code review findings

- Fix type mismatch in search_cache.go: SearchWithCache now returns *yandex.Response instead of *Itinerary
- Fix token bucket refill logic in yandex/client.go to properly accumulate tokens based on refillPerSec
- Fix hardcoded API key in main.go to load from YANDEX_API_KEY environment variable
- Fix missing error handling for JSON encoding in handlers.go RouteGeoJSON function
- Fix incorrect redis.Nil handling in cache/store.go CacheAside.Exists method
- Fix incorrect error return type in station_status.go updateStationStatus to return newStatus instead of empty string
This commit is contained in:
2026-08-17 22:42:08 +03:00
parent 78f662c985
commit 6dcec6a7a5
17 changed files with 331 additions and 349 deletions

View File

@@ -8,8 +8,8 @@ import (
// Metrics holds all observability metrics for the trip planner service.
type Metrics struct {
// Cache metrics per layer
CacheHits map[string]int64 // per-layer hit counts (city, station, search)
CacheMisses map[string]int64 // per-layer miss counts
CacheHits map[string]int64 // per-layer hit counts (city, station, search)
CacheMisses map[string]int64 // per-layer miss counts
// API quota remaining (per key or global)
APIQuotaRemaining int64
@@ -18,27 +18,27 @@ type Metrics struct {
CircuitBreakerTrips int64 // total circuit breaker trips (opened)
// Search metrics
SearchCount int64 // total number of searches
SearchDuration *histogram // distribution of search durations
SearchCount int64 // total number of searches
SearchDuration *histogram // distribution of search durations
// Internal counters
mu sync.Mutex
layerTTLs map[string]time.Duration
mu sync.Mutex
layerTTLs map[string]time.Duration
}
// histogram tracks duration values and computes simple stats.
type histogram struct {
mu sync.Mutex
values []int64 // nanoseconds
maxValues int
mu sync.Mutex
values []int64 // nanoseconds
maxValues int
}
// New creates a new Metrics instance with initialized maps.
func New() *Metrics {
return &Metrics{
CacheHits: make(map[string]int64),
CacheMisses: make(map[string]int64),
layerTTLs: make(map[string]time.Duration),
CacheHits: make(map[string]int64),
CacheMisses: make(map[string]int64),
layerTTLs: make(map[string]time.Duration),
SearchDuration: &histogram{maxValues: 1000},
}
}
@@ -111,14 +111,14 @@ func (m *Metrics) GetMetricsJSON() map[string]interface{} {
}
result := map[string]interface{}{
"cache_hits": m.CacheHits,
"cache_misses": m.CacheMisses,
"cache_hit_rate": m.getOverallHitRate(),
"api_quota_remaining": m.APIQuotaRemaining,
"circuit_breaker_trips": m.CircuitBreakerTrips,
"search_count": m.SearchCount,
"cache_hits": m.CacheHits,
"cache_misses": m.CacheMisses,
"cache_hit_rate": m.getOverallHitRate(),
"api_quota_remaining": m.APIQuotaRemaining,
"circuit_breaker_trips": m.CircuitBreakerTrips,
"search_count": m.SearchCount,
"avg_search_duration_ms": avgSearchDuration,
"layer_ttls": m.layerTTLs,
"layer_ttls": m.layerTTLs,
}
return result
}
@@ -152,4 +152,4 @@ func (m *Metrics) GetLayerTTL(layer string) (time.Duration, bool) {
defer m.mu.Unlock()
ttl, ok := m.layerTTLs[layer]
return ttl, ok
}
}