fix(slurm): add default 30s timeout to HTTP client
Replaces http.DefaultClient with a client that has a 30s timeout to prevent indefinite hangs when the Slurm REST API is unresponsive. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -16,6 +17,8 @@ const (
|
|||||||
DefaultBaseURL = "http://localhost:6820/"
|
DefaultBaseURL = "http://localhost:6820/"
|
||||||
// DefaultUserAgent is the default User-Agent header value.
|
// DefaultUserAgent is the default User-Agent header value.
|
||||||
DefaultUserAgent = "slurm-go-sdk"
|
DefaultUserAgent = "slurm-go-sdk"
|
||||||
|
// DefaultTimeout is the default HTTP request timeout.
|
||||||
|
DefaultTimeout = 30 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client manages communication with the Slurm REST API.
|
// Client manages communication with the Slurm REST API.
|
||||||
@@ -85,7 +88,7 @@ type Response struct {
|
|||||||
// http.DefaultClient is used.
|
// http.DefaultClient is used.
|
||||||
func NewClient(baseURL string, httpClient *http.Client) (*Client, error) {
|
func NewClient(baseURL string, httpClient *http.Client) (*Client, error) {
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
httpClient = http.DefaultClient
|
httpClient = &http.Client{Timeout: DefaultTimeout}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedURL, err := url.Parse(baseURL)
|
parsedURL, err := url.Parse(baseURL)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func TestNewClient(t *testing.T) {
|
|||||||
t.Errorf("expected UserAgent %q, got %q", DefaultUserAgent, client.UserAgent)
|
t.Errorf("expected UserAgent %q, got %q", DefaultUserAgent, client.UserAgent)
|
||||||
}
|
}
|
||||||
if client.client == nil {
|
if client.client == nil {
|
||||||
t.Error("expected http.Client to be initialized (nil httpClient should default to http.DefaultClient)")
|
t.Error("expected http.Client to be initialized (nil httpClient should create a client with default timeout)")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = NewClient("://invalid", nil)
|
_, err = NewClient("://invalid", nil)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ func defaultClientConfig() *clientConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultHTTPTimeout = 30 * time.Second
|
||||||
|
|
||||||
// WithJWTKey specifies the path to the JWT key file.
|
// WithJWTKey specifies the path to the JWT key file.
|
||||||
func WithJWTKey(path string) ClientOption {
|
func WithJWTKey(path string) ClientOption {
|
||||||
return func(c *clientConfig) error {
|
return func(c *clientConfig) error {
|
||||||
@@ -89,11 +91,12 @@ func NewClientWithOpts(baseURL string, opts ...ClientOption) (*Client, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr := NewJWTAuthTransport(cfg.username, key, transportOpts...)
|
tr := NewJWTAuthTransport(cfg.username, key, transportOpts...)
|
||||||
httpClient = tr.Client()
|
httpClient = &http.Client{
|
||||||
|
Transport: tr,
|
||||||
|
Timeout: defaultHTTPTimeout,
|
||||||
|
}
|
||||||
} else if cfg.httpClient != nil {
|
} else if cfg.httpClient != nil {
|
||||||
httpClient = cfg.httpClient
|
httpClient = cfg.httpClient
|
||||||
} else {
|
|
||||||
httpClient = http.DefaultClient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewClient(baseURL, httpClient)
|
return NewClient(baseURL, httpClient)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package slurm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -61,8 +60,8 @@ func TestNewClientWithOpts_BackwardCompatible(t *testing.T) {
|
|||||||
if client == nil {
|
if client == nil {
|
||||||
t.Fatal("expected non-nil client")
|
t.Fatal("expected non-nil client")
|
||||||
}
|
}
|
||||||
if client.client != http.DefaultClient {
|
if client.client.Timeout != DefaultTimeout {
|
||||||
t.Error("expected http.DefaultClient when no options provided")
|
t.Errorf("expected Timeout=%v, got %v", DefaultTimeout, client.client.Timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user