mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 10:18:59 +02:00
refactor(api): restructured API for type safety, maintainability and docs generation
- These changes makes the API incombatible with previous versions - Added new types for error handling, success responses, and health checks. - Updated health check logic to utilize the new types for better clarity and structure. - Refactored existing handlers to improve response consistency and error handling. - Updated Makefile to include a new target for generating API types from Swagger. - Updated "new agent" API to respond an encrypted cert pair
This commit is contained in:
166
internal/types/health.go
Normal file
166
internal/types/health.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/task"
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||
)
|
||||
|
||||
type (
|
||||
HealthStatus uint8
|
||||
|
||||
HealthCheckResult struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
Detail string `json:"detail"`
|
||||
Latency time.Duration `json:"latency"`
|
||||
} // @name HealthCheckResult
|
||||
WithHealthInfo interface {
|
||||
Status() HealthStatus
|
||||
Uptime() time.Duration
|
||||
Latency() time.Duration
|
||||
Detail() string
|
||||
}
|
||||
HealthMonitor interface {
|
||||
task.TaskStarter
|
||||
task.TaskFinisher
|
||||
fmt.Stringer
|
||||
WithHealthInfo
|
||||
Name() string
|
||||
json.Marshaler
|
||||
}
|
||||
HealthChecker interface {
|
||||
CheckHealth() (result *HealthCheckResult, err error)
|
||||
URL() *url.URL
|
||||
Config() *HealthCheckConfig
|
||||
UpdateURL(url *url.URL)
|
||||
}
|
||||
HealthMonCheck interface {
|
||||
HealthMonitor
|
||||
HealthChecker
|
||||
}
|
||||
HealthJSON struct {
|
||||
Name string `json:"name"`
|
||||
Config *HealthCheckConfig `json:"config"`
|
||||
Started int64 `json:"started"`
|
||||
StartedStr string `json:"startedStr"`
|
||||
Status string `json:"status"`
|
||||
Uptime float64 `json:"uptime"`
|
||||
UptimeStr string `json:"uptimeStr"`
|
||||
Latency float64 `json:"latency"`
|
||||
LatencyStr string `json:"latencyStr"`
|
||||
LastSeen int64 `json:"lastSeen"`
|
||||
LastSeenStr string `json:"lastSeenStr"`
|
||||
Detail string `json:"detail"`
|
||||
URL string `json:"url"`
|
||||
Extra *HealthExtra `json:"extra" extensions:"x-nullable"`
|
||||
} // @name HealthJSON
|
||||
|
||||
HealthJSONRepr struct {
|
||||
Name string
|
||||
Config *HealthCheckConfig
|
||||
Status HealthStatus
|
||||
Started time.Time
|
||||
Uptime time.Duration
|
||||
Latency time.Duration
|
||||
LastSeen time.Time
|
||||
Detail string
|
||||
URL *url.URL
|
||||
Extra *HealthExtra
|
||||
}
|
||||
|
||||
HealthExtra struct {
|
||||
Config *LoadBalancerConfig `json:"config"`
|
||||
Pool map[string]any `json:"pool"`
|
||||
} // @name HealthExtra
|
||||
)
|
||||
|
||||
const (
|
||||
StatusUnknown HealthStatus = 0
|
||||
StatusHealthy HealthStatus = (1 << iota)
|
||||
StatusNapping
|
||||
StatusStarting
|
||||
StatusUnhealthy
|
||||
StatusError
|
||||
|
||||
NumStatuses int = iota - 1
|
||||
|
||||
HealthyMask = StatusHealthy | StatusNapping | StatusStarting
|
||||
IdlingMask = StatusNapping | StatusStarting
|
||||
)
|
||||
|
||||
func NewHealthStatusFromString(s string) HealthStatus {
|
||||
switch s {
|
||||
case "healthy":
|
||||
return StatusHealthy
|
||||
case "unhealthy":
|
||||
return StatusUnhealthy
|
||||
case "napping":
|
||||
return StatusNapping
|
||||
case "starting":
|
||||
return StatusStarting
|
||||
case "error":
|
||||
return StatusError
|
||||
default:
|
||||
return StatusUnknown
|
||||
}
|
||||
}
|
||||
|
||||
func (s HealthStatus) String() string {
|
||||
switch s {
|
||||
case StatusHealthy:
|
||||
return "healthy"
|
||||
case StatusUnhealthy:
|
||||
return "unhealthy"
|
||||
case StatusNapping:
|
||||
return "napping"
|
||||
case StatusStarting:
|
||||
return "starting"
|
||||
case StatusError:
|
||||
return "error"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func (s HealthStatus) Good() bool {
|
||||
return s&HealthyMask != 0
|
||||
}
|
||||
|
||||
func (s HealthStatus) Bad() bool {
|
||||
return s&HealthyMask == 0
|
||||
}
|
||||
|
||||
func (s HealthStatus) Idling() bool {
|
||||
return s&IdlingMask != 0
|
||||
}
|
||||
|
||||
func (jsonRepr *HealthJSONRepr) MarshalJSON() ([]byte, error) {
|
||||
var url string
|
||||
if jsonRepr.URL != nil {
|
||||
url = jsonRepr.URL.String()
|
||||
}
|
||||
if url == "http://:0" {
|
||||
url = ""
|
||||
}
|
||||
return json.Marshal(HealthJSON{
|
||||
Name: jsonRepr.Name,
|
||||
Config: jsonRepr.Config,
|
||||
Started: jsonRepr.Started.Unix(),
|
||||
StartedStr: strutils.FormatTime(jsonRepr.Started),
|
||||
Status: jsonRepr.Status.String(),
|
||||
Uptime: jsonRepr.Uptime.Seconds(),
|
||||
UptimeStr: strutils.FormatDuration(jsonRepr.Uptime),
|
||||
Latency: jsonRepr.Latency.Seconds(),
|
||||
LatencyStr: strconv.Itoa(int(jsonRepr.Latency.Milliseconds())) + " ms",
|
||||
LastSeen: jsonRepr.LastSeen.Unix(),
|
||||
LastSeenStr: strutils.FormatLastSeen(jsonRepr.LastSeen),
|
||||
Detail: jsonRepr.Detail,
|
||||
URL: url,
|
||||
Extra: jsonRepr.Extra,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user