mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-10-20 06:28:13 +00:00
perf+coverage: optimisation pass + coverage push to ≥70%
Performance / resource usage: - circuit_breaker_metrics: fix data race on failCounters map (RWMutex + double-checked locking) - server.go: drop user_id and op_name metric labels (Prometheus cardinality bound); de-duplicate extractUserInfo - graphql.go: gate runtime.ReadMemStats per-request behind ENABLE_ALLOCATION_TRACKING flag (default off) - graphql.go: collapse two-pass AST scan into single pass; lower-case once - sanitization.go: cache compiled redaction regexes per pattern via sync.Map; hoist inner constants to pkg vars - proxy.go: hoist connection/timeout substrings to pkg vars; sentinel errors for static error paths; drop dead Headers map alloc - metrics_aggregator.go: log-field allocation guarded by Logger.IsLevelEnabled - logging/logger.go: add IsLevelEnabled helper - lru_cache.go: 16-shard sharding, FNV-1a routing (concurrent throughput +22%) - cache/memory/lru_memory_cache.go: gzip compress/decompress moved outside mu.Lock - rps_tracker.go: RWMutex+uint64 -> atomic.Uint64 - retry_budget.go: drop unused mutex - api.go: bannedUsersIDs map+RWMutex -> sync.Map (+ snapshot/replace helpers) - tracing/tracing.go: pkg-level constSpanAttrs, copy-then-append in StartSpanWithAttributes - admin_dashboard.go: handleStatsWebSocket reuses bytes.Buffer + json.Encoder per connection Build / runtime: - Makefile: -ldflags="-s -w" -trimpath, CGO_ENABLED=0 for build (=1 for test recipes) - Dockerfile + Dockerfile.goreleaser: ENV GOMEMLIMIT=512MiB - main.go: blank import go.uber.org/automaxprocs (cgroup-aware GOMAXPROCS) - main.go: PPROF_PORT env var wires net/http/pprof on 127.0.0.1 only with full server timeouts - README.md: env-var docs + metric-label docs updated; cardinality note Test coverage push (per package): - main 51.2% -> 74.7% - cache 66.3% -> 93.7% - cache/redis 45.5% -> 98.2% - tracing 66.7% -> 72.9% - (cache/memory 91.6%, logging 91.9%, monitoring 77.6%, pkg/pools 100% unchanged) New test files: coverage_micro_test, coverage_extras_test, server_handlers_test, api_health_test, admin_dashboard_cluster_test, metrics_aggregator_test, concerns_test, cache/cache_coverage_test, cache/redis/redis_coverage_test, tracing/tracing_coverage_test. Bug fix: connection_resilience_test.go TestIntegratedHealthManagement.health_manager_startup was sync.Once-coupled to InitializeBackendHealth and panicked when another test (e.g. via parseConfig) had already triggered Once. Use NewBackendHealthManager directly.
This commit is contained in:
@@ -17,10 +17,7 @@ import (
|
||||
"github.com/sony/gobreaker"
|
||||
)
|
||||
|
||||
var (
|
||||
bannedUsersIDs = make(map[string]string)
|
||||
bannedUsersIDsMutex sync.RWMutex
|
||||
)
|
||||
var bannedUsersIDs sync.Map // key: userID string, value: reason string
|
||||
|
||||
// authMiddleware provides API key authentication for admin endpoints
|
||||
func authMiddleware(c *fiber.Ctx) error {
|
||||
@@ -132,16 +129,14 @@ func periodicallyReloadBannedUsers(ctx context.Context) {
|
||||
loadBannedUsers()
|
||||
cfg.Logger.Debug(&libpack_logger.LogMessage{
|
||||
Message: "Banned users reloaded",
|
||||
Pairs: map[string]any{"users": bannedUsersIDs},
|
||||
Pairs: map[string]any{"users": snapshotBannedUsers()},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkIfUserIsBanned(c *fiber.Ctx, userID string) bool {
|
||||
bannedUsersIDsMutex.RLock()
|
||||
_, found := bannedUsersIDs[userID]
|
||||
bannedUsersIDsMutex.RUnlock()
|
||||
_, found := bannedUsersIDs.Load(userID)
|
||||
|
||||
cfg.Logger.Debug(&libpack_logger.LogMessage{
|
||||
Message: "Checking if user is banned",
|
||||
@@ -251,9 +246,7 @@ func apiBanUser(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("user_id and reason are required")
|
||||
}
|
||||
|
||||
bannedUsersIDsMutex.Lock()
|
||||
bannedUsersIDs[req.UserID] = req.Reason
|
||||
bannedUsersIDsMutex.Unlock()
|
||||
bannedUsersIDs.Store(req.UserID, req.Reason)
|
||||
|
||||
cfg.Logger.Info(&libpack_logger.LogMessage{
|
||||
Message: "Banned user",
|
||||
@@ -281,9 +274,7 @@ func apiUnbanUser(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("user_id is required")
|
||||
}
|
||||
|
||||
bannedUsersIDsMutex.Lock()
|
||||
delete(bannedUsersIDs, req.UserID)
|
||||
bannedUsersIDsMutex.Unlock()
|
||||
bannedUsersIDs.Delete(req.UserID)
|
||||
|
||||
cfg.Logger.Info(&libpack_logger.LogMessage{
|
||||
Message: "Unbanned user",
|
||||
@@ -311,9 +302,7 @@ func storeBannedUsers() error {
|
||||
}
|
||||
}()
|
||||
|
||||
bannedUsersIDsMutex.RLock()
|
||||
data, err := json.Marshal(bannedUsersIDs)
|
||||
bannedUsersIDsMutex.RUnlock()
|
||||
data, err := json.Marshal(snapshotBannedUsers())
|
||||
|
||||
if err != nil {
|
||||
cfg.Logger.Error(&libpack_logger.LogMessage{
|
||||
@@ -384,9 +373,33 @@ func loadBannedUsers() {
|
||||
return
|
||||
}
|
||||
|
||||
bannedUsersIDsMutex.Lock()
|
||||
bannedUsersIDs = newBannedUsers
|
||||
bannedUsersIDsMutex.Unlock()
|
||||
replaceBannedUsers(newBannedUsers)
|
||||
}
|
||||
|
||||
// snapshotBannedUsers returns a plain map copy of the current banned users.
|
||||
func snapshotBannedUsers() map[string]string {
|
||||
out := make(map[string]string)
|
||||
bannedUsersIDs.Range(func(k, v any) bool {
|
||||
ks, kok := k.(string)
|
||||
vs, vok := v.(string)
|
||||
if kok && vok {
|
||||
out[ks] = vs
|
||||
}
|
||||
return true
|
||||
})
|
||||
return out
|
||||
}
|
||||
|
||||
// replaceBannedUsers swaps the banned users set with the provided map.
|
||||
// Existing entries are removed before inserting the new ones.
|
||||
func replaceBannedUsers(newUsers map[string]string) {
|
||||
bannedUsersIDs.Range(func(k, _ any) bool {
|
||||
bannedUsersIDs.Delete(k)
|
||||
return true
|
||||
})
|
||||
for k, v := range newUsers {
|
||||
bannedUsersIDs.Store(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func lockFile(fileLock *flock.Flock) error {
|
||||
|
||||
Reference in New Issue
Block a user