mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-07-10 06:52:00 +00:00
Add active healtchecks to verify the connectivity.
This commit is contained in:
@@ -4,8 +4,10 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nvm/kportal/internal/config"
|
||||
"github.com/nvm/kportal/internal/healthcheck"
|
||||
"github.com/nvm/kportal/internal/k8s"
|
||||
)
|
||||
|
||||
@@ -25,6 +27,7 @@ type Manager struct {
|
||||
resolver *k8s.ResourceResolver
|
||||
portForwarder *k8s.PortForwarder
|
||||
portChecker *PortChecker
|
||||
healthChecker *healthcheck.Checker
|
||||
verbose bool
|
||||
currentConfig *config.Config
|
||||
statusUI StatusUpdater
|
||||
@@ -40,12 +43,16 @@ func NewManager(verbose bool) *Manager {
|
||||
resolver := k8s.NewResourceResolver(clientPool)
|
||||
portForwarder := k8s.NewPortForwarder(clientPool, resolver)
|
||||
|
||||
// Create health checker: check every 5 seconds with 2 second timeout
|
||||
healthChecker := healthcheck.NewChecker(5*time.Second, 2*time.Second)
|
||||
|
||||
return &Manager{
|
||||
workers: make(map[string]*ForwardWorker),
|
||||
clientPool: clientPool,
|
||||
resolver: resolver,
|
||||
portForwarder: portForwarder,
|
||||
portChecker: NewPortChecker(),
|
||||
healthChecker: healthChecker,
|
||||
verbose: verbose,
|
||||
}
|
||||
}
|
||||
@@ -99,6 +106,9 @@ func (m *Manager) Start(cfg *config.Config) error {
|
||||
func (m *Manager) Stop() {
|
||||
log.Printf("Stopping all port-forwards...")
|
||||
|
||||
// Stop health checker first
|
||||
m.healthChecker.Stop()
|
||||
|
||||
m.workersMu.Lock()
|
||||
workers := make([]*ForwardWorker, 0, len(m.workers))
|
||||
for _, worker := range m.workers {
|
||||
@@ -248,8 +258,15 @@ func (m *Manager) startWorker(fwd config.Forward) error {
|
||||
m.statusUI.AddForward(fwd.ID(), &fwd)
|
||||
}
|
||||
|
||||
// Register with health checker
|
||||
m.healthChecker.Register(fwd.ID(), fwd.LocalPort, func(forwardID string, status healthcheck.Status) {
|
||||
if m.statusUI != nil {
|
||||
m.statusUI.UpdateStatus(forwardID, string(status))
|
||||
}
|
||||
})
|
||||
|
||||
// Create and start worker
|
||||
worker := NewForwardWorker(fwd, m.portForwarder, m.verbose, m.statusUI)
|
||||
worker := NewForwardWorker(fwd, m.portForwarder, m.verbose, m.statusUI, m.healthChecker)
|
||||
worker.Start()
|
||||
|
||||
// Store worker
|
||||
@@ -269,6 +286,9 @@ func (m *Manager) stopWorker(id string) error {
|
||||
delete(m.workers, id)
|
||||
m.workersMu.Unlock()
|
||||
|
||||
// Unregister from health checker
|
||||
m.healthChecker.Unregister(id)
|
||||
|
||||
// Stop the worker
|
||||
worker.Stop()
|
||||
|
||||
|
||||
+12
-11
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/nvm/kportal/internal/config"
|
||||
"github.com/nvm/kportal/internal/healthcheck"
|
||||
"github.com/nvm/kportal/internal/k8s"
|
||||
"github.com/nvm/kportal/internal/retry"
|
||||
)
|
||||
@@ -23,10 +24,11 @@ type ForwardWorker struct {
|
||||
verbose bool
|
||||
lastPod string // Track the last pod we connected to
|
||||
statusUI StatusUpdater
|
||||
healthChecker *healthcheck.Checker
|
||||
}
|
||||
|
||||
// NewForwardWorker creates a new ForwardWorker for a single forward configuration.
|
||||
func NewForwardWorker(fwd config.Forward, portForwarder *k8s.PortForwarder, verbose bool, statusUI StatusUpdater) *ForwardWorker {
|
||||
func NewForwardWorker(fwd config.Forward, portForwarder *k8s.PortForwarder, verbose bool, statusUI StatusUpdater, healthChecker *healthcheck.Checker) *ForwardWorker {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
return &ForwardWorker{
|
||||
@@ -38,6 +40,7 @@ func NewForwardWorker(fwd config.Forward, portForwarder *k8s.PortForwarder, verb
|
||||
doneChan: make(chan struct{}),
|
||||
verbose: verbose,
|
||||
statusUI: statusUI,
|
||||
healthChecker: healthChecker,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,22 +91,20 @@ func (w *ForwardWorker) run() {
|
||||
|
||||
// Check if pod changed (restart detected)
|
||||
if w.lastPod != "" && w.lastPod != podName {
|
||||
if w.statusUI != nil {
|
||||
w.statusUI.UpdateStatus(w.forward.ID(), "Reconnecting")
|
||||
if w.healthChecker != nil {
|
||||
w.healthChecker.MarkReconnecting(w.forward.ID())
|
||||
}
|
||||
log.Printf("[%s] Switched to new pod: %s → %s", w.forward.ID(), w.lastPod, podName)
|
||||
} else if w.lastPod == "" {
|
||||
log.Printf("[%s] Forwarding %s → localhost:%d",
|
||||
w.forward.ID(), w.forward.String(), w.forward.LocalPort)
|
||||
if w.healthChecker != nil {
|
||||
w.healthChecker.MarkStarting(w.forward.ID())
|
||||
}
|
||||
}
|
||||
|
||||
w.lastPod = podName
|
||||
|
||||
// Update status to active
|
||||
if w.statusUI != nil {
|
||||
w.statusUI.UpdateStatus(w.forward.ID(), "Active")
|
||||
}
|
||||
|
||||
// Establish port-forward connection
|
||||
err = w.establishForward(podName)
|
||||
|
||||
@@ -114,9 +115,9 @@ func (w *ForwardWorker) run() {
|
||||
return
|
||||
}
|
||||
|
||||
// Update status to error
|
||||
if w.statusUI != nil {
|
||||
w.statusUI.UpdateStatus(w.forward.ID(), "Reconnecting")
|
||||
// Update status to reconnecting
|
||||
if w.healthChecker != nil {
|
||||
w.healthChecker.MarkReconnecting(w.forward.ID())
|
||||
}
|
||||
|
||||
// Log the error
|
||||
|
||||
Reference in New Issue
Block a user