fix: properly handle PBS connection timeouts with granular timeout settings

The real issue was not the overall timeout duration, but that DNS resolution and TLS handshake could hang indefinitely. Added specific timeouts for:
- DNS resolution/connection: 10 seconds
- TLS handshake: 10 seconds
- Response headers: 10 seconds

This prevents the connection from hanging on DNS lookup (like with pve-backup.lan) or during TLS negotiation, which was causing the 'context deadline exceeded' errors. (addresses #424)
This commit is contained in:
Pulse Monitor
2025-09-06 10:07:10 +00:00
parent c41013c5c1
commit 74359955ad
2 changed files with 13 additions and 8 deletions
+3 -8
View File
@@ -226,11 +226,7 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) {
Host: pbsNode.Host,
}
// Test connection with a shorter timeout for PBS specifically
// PBS can be slow to respond, so we use a separate 30-second timeout
pbsCtx, pbsCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer pbsCancel()
// Test connection
testCfg := pbs.ClientConfig{
Host: pbsNode.Host,
User: pbsNode.User,
@@ -239,7 +235,6 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) {
TokenValue: pbsNode.TokenValue,
Fingerprint: pbsNode.Fingerprint,
VerifySSL: pbsNode.VerifySSL,
Timeout: 30 * time.Second, // Set explicit timeout in client config
}
client, err := pbs.NewClient(testCfg)
@@ -247,8 +242,8 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) {
pbsDiag.Connected = false
pbsDiag.Error = err.Error()
} else {
// Try to get version with PBS-specific context
if version, err := client.GetVersion(pbsCtx); err != nil {
// Try to get version
if version, err := client.GetVersion(ctx); err != nil {
pbsDiag.Connected = false
pbsDiag.Error = "Connection established but version check failed: " + err.Error()
} else {
+10
View File
@@ -6,6 +6,7 @@ import (
"crypto/x509"
"encoding/hex"
"fmt"
"net"
"net/http"
"strings"
"time"
@@ -52,6 +53,15 @@ func CreateHTTPClientWithTimeout(verifySSL bool, fingerprint string, timeout tim
MaxConnsPerHost: 20, // Limit concurrent connections per host
IdleConnTimeout: 90 * time.Second,
DisableCompression: true, // Disable compression for lower latency
// Add specific timeouts for DNS, TLS handshake, and response headers
// These prevent hanging on DNS resolution or TLS negotiation
DialContext: (&net.Dialer{
Timeout: 10 * time.Second, // Connection timeout
KeepAlive: 30 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second, // TLS handshake timeout
ResponseHeaderTimeout: 10 * time.Second, // Time to wait for response headers
ExpectContinueTimeout: 1 * time.Second,
}
if !verifySSL && fingerprint == "" {