chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package externalprobe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceNamePattern = regexp.MustCompile(`^[a-z][a-z0-9-]{1,31}$`)
|
||||
dependencyPattern = regexp.MustCompile(`^[a-z][a-z0-9_]{1,63}$`)
|
||||
)
|
||||
|
||||
func PostgresObserver(pool *pgxpool.Pool, serviceName string) (Observer, error) {
|
||||
if pool == nil || !serviceNamePattern.MatchString(serviceName) {
|
||||
return nil, errors.New("external probe database and service name are required")
|
||||
}
|
||||
return func(ctx context.Context, observation Observation) error {
|
||||
if !dependencyPattern.MatchString(observation.Dependency) {
|
||||
return errors.New("external probe dependency name is invalid")
|
||||
}
|
||||
if observation.Interval <= 0 {
|
||||
return errors.New("external probe interval is required")
|
||||
}
|
||||
latencyMS := observation.Latency.Milliseconds()
|
||||
if latencyMS < 0 {
|
||||
latencyMS = 0
|
||||
}
|
||||
intervalMS := observation.Interval.Milliseconds()
|
||||
if intervalMS < 1 {
|
||||
intervalMS = 1
|
||||
}
|
||||
checkedAt := observation.CheckedAt.UTC()
|
||||
if checkedAt.IsZero() {
|
||||
checkedAt = time.Now().UTC()
|
||||
}
|
||||
status := "AVAILABLE"
|
||||
if !observation.Available {
|
||||
status = "UNAVAILABLE"
|
||||
if observation.ErrorCode == "" {
|
||||
observation.ErrorCode = "PROBE_FAILED"
|
||||
}
|
||||
}
|
||||
_, err := pool.Exec(ctx, `
|
||||
INSERT INTO external_dependency_probe_state(service_name,dependency,status,checked_at,last_success_at,last_failure_at,last_error_code,latency_ms,probe_interval_ms,consecutive_failures)
|
||||
VALUES($1,$2,$3::varchar,$4::timestamptz,CASE WHEN $3::varchar='AVAILABLE' THEN $4::timestamptz END,CASE WHEN $3::varchar='UNAVAILABLE' THEN $4::timestamptz END,NULLIF($5::varchar,''),$6,$7,CASE WHEN $3::varchar='UNAVAILABLE' THEN 1 ELSE 0 END)
|
||||
ON CONFLICT(service_name,dependency) DO UPDATE SET
|
||||
status=EXCLUDED.status,
|
||||
checked_at=EXCLUDED.checked_at,
|
||||
last_success_at=CASE WHEN EXCLUDED.status='AVAILABLE' THEN EXCLUDED.checked_at ELSE external_dependency_probe_state.last_success_at END,
|
||||
last_failure_at=CASE WHEN EXCLUDED.status='UNAVAILABLE' THEN EXCLUDED.checked_at ELSE external_dependency_probe_state.last_failure_at END,
|
||||
last_error_code=EXCLUDED.last_error_code,
|
||||
latency_ms=EXCLUDED.latency_ms,
|
||||
probe_interval_ms=EXCLUDED.probe_interval_ms,
|
||||
consecutive_failures=CASE WHEN EXCLUDED.status='AVAILABLE' THEN 0 ELSE external_dependency_probe_state.consecutive_failures+1 END,
|
||||
updated_at=now()`, serviceName, observation.Dependency, status, checkedAt, observation.ErrorCode, latencyMS, intervalMS)
|
||||
return err
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ReconcilePostgresState(ctx context.Context, pool *pgxpool.Pool, serviceName string, dependencies []string) error {
|
||||
if pool == nil || !serviceNamePattern.MatchString(serviceName) {
|
||||
return errors.New("external probe database and service name are required")
|
||||
}
|
||||
for _, dependency := range dependencies {
|
||||
if !dependencyPattern.MatchString(dependency) {
|
||||
return errors.New("external probe dependency name is invalid")
|
||||
}
|
||||
}
|
||||
_, err := pool.Exec(ctx, `DELETE FROM external_dependency_probe_state WHERE service_name=$1 AND NOT (dependency=ANY(COALESCE($2::text[],ARRAY[]::text[])))`, serviceName, dependencies)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user