platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
114
selective-vpn-api/app/transport_client_runtime.go
Normal file
114
selective-vpn-api/app/transport_client_runtime.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func applyTransportLifecycleFailure(it *TransportClient, action string, now time.Time, backendID string, result transportBackendActionResult) {
|
||||
ts := now.Format(time.RFC3339)
|
||||
prev := it.Status
|
||||
rt := transportRuntimeSnapshot(*it, now)
|
||||
if strings.TrimSpace(backendID) != "" {
|
||||
rt.Backend = backendID
|
||||
}
|
||||
rt.LastAction = action
|
||||
rt.LastActionAt = ts
|
||||
rt.LastExitCode = result.ExitCode
|
||||
msg := strings.TrimSpace(result.Message)
|
||||
if msg == "" {
|
||||
msg = "transport backend action failed"
|
||||
}
|
||||
rt.LastError = TransportClientError{
|
||||
Code: strings.TrimSpace(result.Code),
|
||||
Message: msg,
|
||||
Retryable: result.Retryable,
|
||||
At: ts,
|
||||
}
|
||||
switch action {
|
||||
case "start", "restart":
|
||||
it.Status = TransportClientDegraded
|
||||
case "stop":
|
||||
// Keep previous state on failed stop to avoid false down transitions.
|
||||
}
|
||||
if prev != it.Status {
|
||||
rt.Metrics.StateChanges++
|
||||
rt.Metrics.LastTransitionAt = ts
|
||||
}
|
||||
rt.Metrics.UptimeSec = transportUptimeSec(it.Status, rt.StartedAt, now)
|
||||
it.Health.LastCheck = ts
|
||||
it.Health.LastError = msg
|
||||
it.UpdatedAt = ts
|
||||
it.Runtime = rt
|
||||
}
|
||||
|
||||
func applyTransportProvisionResult(it *TransportClient, now time.Time, backendID string, result transportBackendActionResult) {
|
||||
ts := now.Format(time.RFC3339)
|
||||
rt := transportRuntimeSnapshot(*it, now)
|
||||
if strings.TrimSpace(backendID) != "" {
|
||||
rt.Backend = backendID
|
||||
}
|
||||
rt.LastAction = "provision"
|
||||
rt.LastActionAt = ts
|
||||
rt.LastExitCode = result.ExitCode
|
||||
if result.OK {
|
||||
rt.LastError = TransportClientError{}
|
||||
it.Health.LastError = ""
|
||||
} else {
|
||||
msg := strings.TrimSpace(result.Message)
|
||||
if msg == "" {
|
||||
msg = "transport backend provision failed"
|
||||
}
|
||||
rt.LastError = TransportClientError{
|
||||
Code: strings.TrimSpace(result.Code),
|
||||
Message: msg,
|
||||
Retryable: result.Retryable,
|
||||
At: ts,
|
||||
}
|
||||
it.Health.LastError = msg
|
||||
}
|
||||
it.Health.LastCheck = ts
|
||||
it.UpdatedAt = ts
|
||||
it.Runtime = rt
|
||||
}
|
||||
|
||||
func applyTransportLifecycleAction(it *TransportClient, action string, now time.Time) {
|
||||
ts := now.Format(time.RFC3339)
|
||||
prev := it.Status
|
||||
rt := transportRuntimeSnapshot(*it, now)
|
||||
|
||||
rt.LastAction = action
|
||||
rt.LastActionAt = ts
|
||||
rt.LastExitCode = 0
|
||||
rt.LastError = TransportClientError{}
|
||||
|
||||
switch action {
|
||||
case "start":
|
||||
it.Status = TransportClientUp
|
||||
it.Enabled = true
|
||||
case "stop":
|
||||
it.Status = TransportClientDown
|
||||
case "restart":
|
||||
it.Status = TransportClientUp
|
||||
rt.Metrics.Restarts++
|
||||
}
|
||||
if prev != it.Status {
|
||||
rt.Metrics.StateChanges++
|
||||
rt.Metrics.LastTransitionAt = ts
|
||||
}
|
||||
if it.Status == TransportClientUp {
|
||||
if prev != TransportClientUp || strings.TrimSpace(rt.StartedAt) == "" {
|
||||
rt.StartedAt = ts
|
||||
}
|
||||
} else if it.Status == TransportClientDown {
|
||||
rt.StoppedAt = ts
|
||||
}
|
||||
rt.Metrics.UptimeSec = transportUptimeSec(it.Status, rt.StartedAt, now)
|
||||
|
||||
it.Health.LastCheck = ts
|
||||
if it.Status == TransportClientUp {
|
||||
it.Health.LastError = ""
|
||||
}
|
||||
it.UpdatedAt = ts
|
||||
it.Runtime = rt
|
||||
}
|
||||
Reference in New Issue
Block a user