package health import ( "context" "fmt" "time" proxyDomain "proxy-pool/internal/domain/proxy" ) // Candidate is one bounded due-index item. It identifies a check without // carrying endpoint credentials or any persistence-specific representation. type Candidate struct { ProxyID string State proxyDomain.State Level Level RoutingName string TargetURL string DueAt time.Time } // CandidateIdentity is stable across Controller instances and is suitable for // deterministic task identity and jitter derivation. func CandidateIdentity(candidate Candidate) string { return candidate.ProxyID + "\x00" + string(candidate.Level) + "\x00" + candidate.RoutingName + "\x00" + candidate.TargetURL } type Priority uint8 const ( PriorityFetched Priority = iota + 1 PrioritySuspect PriorityUnhealthy PriorityAvailable ) // PlannedTask is transport-neutral work ready for a shared leased task store. type PlannedTask struct { Candidate Candidate Priority Priority Deadline time.Time Attempts int } // TaskMaterial is short-lived proxy connection material. It crosses only the // authenticated Checker control stream and must never be logged or persisted // by a task queue. type TaskMaterial struct { Protocol proxyDomain.Scheme Host string Port uint16 SecretRef string CredentialVersion string Username string Password string } func (TaskMaterial) Format(state fmt.State, _ rune) { _, _ = state.Write([]byte("health.TaskMaterial{Credentials:}")) } // TaskMaterialResolver resolves endpoint and credential material only when a // task lease is granted. Checkers do not directly access Redis or PostgreSQL. type TaskMaterialResolver interface { ResolveCheckTask(context.Context, Candidate) (TaskMaterial, error) } type TaskMaterialResolverFunc func(context.Context, Candidate) (TaskMaterial, error) func (resolver TaskMaterialResolverFunc) ResolveCheckTask(ctx context.Context, candidate Candidate) (TaskMaterial, error) { return resolver(ctx, candidate) } // TaskClaim is one bounded pull request from a Checker process. type TaskClaim struct { CheckerID string InstanceID string MaxInFlight int SupportedLevels []Level } // LeasedTask is a Controller-assigned task. Its material is kept in memory // only for the task lease duration and is redacted from formatted values. type LeasedTask struct { TaskID string LeaseToken string ProxyID string Protocol proxyDomain.Scheme Host string Port uint16 SecretRef string CredentialVersion string Username string Password string Level Level RoutingName string TargetURL string Deadline time.Time Attempts int } func (LeasedTask) Format(state fmt.State, _ rune) { _, _ = state.Write([]byte("health.LeasedTask{Credentials:}")) } // TaskBroker is the shared task lease boundary. Schedulers offer bounded // work, Checkers claim work, and observation commits are fenced by a lease. type TaskBroker interface { Offer(context.Context, []PlannedTask) (int, error) Claim(context.Context, TaskClaim) ([]LeasedTask, error) AuthorizeObservation(context.Context, string, string, Observation, time.Time) error CompleteObservation(context.Context, string, string, Observation, time.Time) error }