mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00

- Incorrect name being shown on dashboard "Proxies page" - Apps being shown when homepage.show is false - Load balanced routes are shown on homepage instead of the load balancer - Route with idlewatcher will now be removed on container destroy - Idlewatcher panic - Performance improvement - Idlewatcher infinitely loading - Reload stucked / not working properly - Streams stuck on shutdown / reload - etc... Added: - support idlewatcher for loadbalanced routes - partial implementation for stream type idlewatcher Issues: - graceful shutdown
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package idlewatcher
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/yusing/go-proxy/internal/docker"
|
|
E "github.com/yusing/go-proxy/internal/error"
|
|
)
|
|
|
|
type (
|
|
Config struct {
|
|
IdleTimeout time.Duration `json:"idle_timeout,omitempty"`
|
|
WakeTimeout time.Duration `json:"wake_timeout,omitempty"`
|
|
StopTimeout int `json:"stop_timeout,omitempty"` // docker api takes integer seconds for timeout argument
|
|
StopMethod StopMethod `json:"stop_method,omitempty"`
|
|
StopSignal Signal `json:"stop_signal,omitempty"`
|
|
|
|
DockerHost string `json:"docker_host,omitempty"`
|
|
ContainerName string `json:"container_name,omitempty"`
|
|
ContainerID string `json:"container_id,omitempty"`
|
|
ContainerRunning bool `json:"container_running,omitempty"`
|
|
}
|
|
StopMethod string
|
|
Signal string
|
|
)
|
|
|
|
const (
|
|
StopMethodPause StopMethod = "pause"
|
|
StopMethodStop StopMethod = "stop"
|
|
StopMethodKill StopMethod = "kill"
|
|
)
|
|
|
|
func ValidateConfig(cont *docker.Container) (cfg *Config, res E.NestedError) {
|
|
if cont == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if cont.IdleTimeout == "" {
|
|
return &Config{
|
|
DockerHost: cont.DockerHost,
|
|
ContainerName: cont.ContainerName,
|
|
ContainerID: cont.ContainerID,
|
|
ContainerRunning: cont.Running,
|
|
}, nil
|
|
}
|
|
|
|
b := E.NewBuilder("invalid idlewatcher config")
|
|
defer b.To(&res)
|
|
|
|
idleTimeout, err := validateDurationPostitive(cont.IdleTimeout)
|
|
b.Add(err.Subjectf("%s", "idle_timeout"))
|
|
|
|
wakeTimeout, err := validateDurationPostitive(cont.WakeTimeout)
|
|
b.Add(err.Subjectf("%s", "wake_timeout"))
|
|
|
|
stopTimeout, err := validateDurationPostitive(cont.StopTimeout)
|
|
b.Add(err.Subjectf("%s", "stop_timeout"))
|
|
|
|
stopMethod, err := validateStopMethod(cont.StopMethod)
|
|
b.Add(err)
|
|
|
|
signal, err := validateSignal(cont.StopSignal)
|
|
b.Add(err)
|
|
|
|
if err := b.Build(); err != nil {
|
|
return
|
|
}
|
|
|
|
return &Config{
|
|
IdleTimeout: idleTimeout,
|
|
WakeTimeout: wakeTimeout,
|
|
StopTimeout: int(stopTimeout.Seconds()),
|
|
StopMethod: stopMethod,
|
|
StopSignal: signal,
|
|
|
|
DockerHost: cont.DockerHost,
|
|
ContainerName: cont.ContainerName,
|
|
ContainerID: cont.ContainerID,
|
|
ContainerRunning: cont.Running,
|
|
}, nil
|
|
}
|
|
|
|
func validateDurationPostitive(value string) (time.Duration, E.NestedError) {
|
|
d, err := time.ParseDuration(value)
|
|
if err != nil {
|
|
return 0, E.Invalid("duration", value).With(err)
|
|
}
|
|
if d < 0 {
|
|
return 0, E.Invalid("duration", "negative value")
|
|
}
|
|
return d, nil
|
|
}
|
|
|
|
func validateSignal(s string) (Signal, E.NestedError) {
|
|
switch s {
|
|
case "", "SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT",
|
|
"INT", "TERM", "HUP", "QUIT":
|
|
return Signal(s), nil
|
|
}
|
|
|
|
return "", E.Invalid("signal", s)
|
|
}
|
|
|
|
func validateStopMethod(s string) (StopMethod, E.NestedError) {
|
|
sm := StopMethod(s)
|
|
switch sm {
|
|
case StopMethodPause, StopMethodStop, StopMethodKill:
|
|
return sm, nil
|
|
default:
|
|
return "", E.Invalid("stop_method", sm)
|
|
}
|
|
}
|