refactor(httpapi): readiness ping via store backend

ARCH-09: Ping на store.Backend; readiness без прямого pgxpool.Ping в handler.
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-05-20 14:49:26 +07:00
co-authored by Cursor
parent 6fa693156d
commit 33fe8fdd18
4 changed files with 26 additions and 5 deletions
+7 -4
View File
@@ -84,12 +84,15 @@ func (s *Server) handleReady(w http.ResponseWriter, r *http.Request) {
checks := map[string]string{"store": "ok", "jobs": "memory"} checks := map[string]string{"store": "ok", "jobs": "memory"}
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second) ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel() defer cancel()
if s.pgPool != nil { if err := s.store.Ping(ctx); err != nil {
if err := s.pgPool.Ping(ctx); err != nil { checks["store"] = "unavailable"
if s.pgPool != nil {
checks["postgres"] = "unavailable" checks["postgres"] = "unavailable"
writeJSON(w, http.StatusServiceUnavailable, map[string]any{"status": "not_ready", "checks": checks})
return
} }
writeJSON(w, http.StatusServiceUnavailable, map[string]any{"status": "not_ready", "checks": checks})
return
}
if s.pgPool != nil {
checks["postgres"] = "ok" checks["postgres"] = "ok"
} else { } else {
checks["store_backend"] = "memory" checks["store_backend"] = "memory"
+5
View File
@@ -71,6 +71,11 @@ func (p *Postgres) DemoIDs() (tenant, moduleCDN, moduleIP, revision, speaker str
return p.demoTenant, p.demoCDN, p.demoIP, p.demoRev, p.demoSpk return p.demoTenant, p.demoCDN, p.demoIP, p.demoRev, p.demoSpk
} }
// Ping checks PostgreSQL connectivity.
func (p *Postgres) Ping(ctx context.Context) error {
return p.pool.Ping(ctx)
}
func (p *Postgres) MaterializedPrefixStats() (max int, sum int) { func (p *Postgres) MaterializedPrefixStats() (max int, sum int) {
ctx := context.Background() ctx := context.Background()
// Агрегация в БД — не тащим все строки config_revision в память. // Агрегация в БД — не тащим все строки config_revision в память.
+7 -1
View File
@@ -1,6 +1,9 @@
package store package store
import "time" import (
"context"
"time"
)
// Backend is the persistence abstraction for the control plane (memory, PostgreSQL, SQLite). // Backend is the persistence abstraction for the control plane (memory, PostgreSQL, SQLite).
type Backend interface { type Backend interface {
@@ -90,6 +93,9 @@ type Backend interface {
// ASNPrefixCache stores RIPEstat announced-prefixes per ASN (global TTL cache). // ASNPrefixCache stores RIPEstat announced-prefixes per ASN (global TTL cache).
GetASNPrefixCache(asn int64) (*ASNPrefixCacheEntry, bool, error) GetASNPrefixCache(asn int64) (*ASNPrefixCacheEntry, bool, error)
SetASNPrefixCache(asn int64, holder string, prefixes []string) error SetASNPrefixCache(asn int64, holder string, prefixes []string) error
// Ping verifies backend connectivity (no-op for in-memory).
Ping(ctx context.Context) error
} }
// ASNPrefixCacheEntry is a cached RIPEstat response for one ASN. // ASNPrefixCacheEntry is a cached RIPEstat response for one ASN.
+7
View File
@@ -1,6 +1,7 @@
package store package store
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"sort" "sort"
@@ -291,6 +292,12 @@ func (m *Memory) DemoIDs() (tenant, moduleCDN, moduleIP, revision, speaker strin
return m.demoTenantID, m.demoModuleCDN, m.demoModuleIP, m.demoRevisionID, m.demoSpeakerID return m.demoTenantID, m.demoModuleCDN, m.demoModuleIP, m.demoRevisionID, m.demoSpeakerID
} }
// Ping is a no-op for the in-memory backend.
func (m *Memory) Ping(ctx context.Context) error {
_ = ctx
return nil
}
// ListTenantIDs returns tenant ids sorted lexicographically. // ListTenantIDs returns tenant ids sorted lexicographically.
func (m *Memory) ListTenantIDs() ([]string, error) { func (m *Memory) ListTenantIDs() ([]string, error) {
m.mu.RLock() m.mu.RLock()