Procházet zdrojové kódy

refactor(fetcher): use time.Duration for client timeout values

All functions use time.Duration, so instead of converting everywhere, do it once.
gudvinr před 7 měsíci
rodič
revize
30453ad7ec

+ 32 - 2
internal/config/config_test.go

@@ -1607,12 +1607,22 @@ func TestMediaProxyHTTPClientTimeout(t *testing.T) {
 		t.Fatalf(`Parsing failure: %v`, err)
 	}
 
-	expected := 24
+	expected := 24 * time.Second
 	result := opts.MediaProxyHTTPClientTimeout()
 
 	if result != expected {
 		t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
 	}
+
+	sorted := opts.SortedOptions(false)
+	i := slices.IndexFunc(sorted, func(opt *option) bool {
+		return opt.Key == "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT"
+	})
+
+	expectedSerialized := 24
+	if got := sorted[i].Value; got != expectedSerialized {
+		t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
+	}
 }
 
 func TestDefaultMediaProxyHTTPClientTimeoutValue(t *testing.T) {
@@ -1630,6 +1640,16 @@ func TestDefaultMediaProxyHTTPClientTimeoutValue(t *testing.T) {
 	if result != expected {
 		t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
 	}
+
+	sorted := opts.SortedOptions(false)
+	i := slices.IndexFunc(sorted, func(opt *option) bool {
+		return opt.Key == "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT"
+	})
+
+	expectedSerialized := int(defaultMediaProxyHTTPClientTimeout / time.Second)
+	if got := sorted[i].Value; got != expectedSerialized {
+		t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
+	}
 }
 
 func TestMediaProxyCustomURL(t *testing.T) {
@@ -1706,12 +1726,22 @@ func TestHTTPClientTimeout(t *testing.T) {
 		t.Fatalf(`Parsing failure: %v`, err)
 	}
 
-	expected := 42
+	expected := 42 * time.Second
 	result := opts.HTTPClientTimeout()
 
 	if result != expected {
 		t.Fatalf(`Unexpected HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
 	}
+
+	sorted := opts.SortedOptions(false)
+	i := slices.IndexFunc(sorted, func(opt *option) bool {
+		return opt.Key == "HTTP_CLIENT_TIMEOUT"
+	})
+
+	expectedSerialized := 42
+	if got := sorted[i].Value; got != expectedSerialized {
+		t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
+	}
 }
 
 func TestDefaultHTTPClientTimeoutValue(t *testing.T) {

+ 9 - 9
internal/config/options.go

@@ -52,7 +52,7 @@ const (
 	defaultCleanupArchiveUnreadDays           = 180
 	defaultCleanupArchiveBatchSize            = 10000
 	defaultCleanupRemoveSessionsDays          = 30
-	defaultMediaProxyHTTPClientTimeout        = 120
+	defaultMediaProxyHTTPClientTimeout        = 120 * time.Second
 	defaultMediaProxyMode                     = "http-only"
 	defaultMediaResourceTypes                 = "image"
 	defaultMediaProxyURL                      = ""
@@ -74,7 +74,7 @@ const (
 	defaultOauth2OidcProviderName             = "OpenID Connect"
 	defaultOAuth2Provider                     = ""
 	defaultDisableLocalAuth                   = false
-	defaultHTTPClientTimeout                  = 20
+	defaultHTTPClientTimeout                  = 20 * time.Second
 	defaultHTTPClientMaxBodySize              = 15
 	defaultHTTPClientProxy                    = ""
 	defaultHTTPServerTimeout                  = 300 * time.Second
@@ -145,7 +145,7 @@ type options struct {
 	createAdmin                        bool
 	adminUsername                      string
 	adminPassword                      string
-	mediaProxyHTTPClientTimeout        int
+	mediaProxyHTTPClientTimeout        time.Duration
 	mediaProxyMode                     string
 	mediaProxyResourceTypes            []string
 	mediaProxyCustomURL                *url.URL
@@ -165,7 +165,7 @@ type options struct {
 	oidcProviderName                   string
 	oauth2Provider                     string
 	disableLocalAuth                   bool
-	httpClientTimeout                  int
+	httpClientTimeout                  time.Duration
 	httpClientMaxBodySize              int64
 	httpClientProxyURL                 *url.URL
 	httpClientProxies                  []string
@@ -567,8 +567,8 @@ func (o *options) MediaCustomProxyURL() *url.URL {
 	return o.mediaProxyCustomURL
 }
 
-// MediaProxyHTTPClientTimeout returns the time limit in seconds before the proxy HTTP client cancel the request.
-func (o *options) MediaProxyHTTPClientTimeout() int {
+// MediaProxyHTTPClientTimeout returns the time limit before the proxy HTTP client cancel the request.
+func (o *options) MediaProxyHTTPClientTimeout() time.Duration {
 	return o.mediaProxyHTTPClientTimeout
 }
 
@@ -588,7 +588,7 @@ func (o *options) HasSchedulerService() bool {
 }
 
 // HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
-func (o *options) HTTPClientTimeout() int {
+func (o *options) HTTPClientTimeout() time.Duration {
 	return o.httpClientTimeout
 }
 
@@ -743,7 +743,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
 		"HTTP_CLIENT_MAX_BODY_SIZE":              o.httpClientMaxBodySize,
 		"HTTP_CLIENT_PROXIES":                    clientProxyURLsRedacted,
 		"HTTP_CLIENT_PROXY":                      clientProxyURLRedacted,
-		"HTTP_CLIENT_TIMEOUT":                    o.httpClientTimeout,
+		"HTTP_CLIENT_TIMEOUT":                    int(o.httpClientTimeout.Seconds()),
 		"HTTP_CLIENT_USER_AGENT":                 o.httpClientUserAgent,
 		"HTTP_SERVER_TIMEOUT":                    int(o.httpServerTimeout.Seconds()),
 		"HTTP_SERVICE":                           o.httpService,
@@ -774,7 +774,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
 		"POLLING_LIMIT_PER_HOST":                 o.pollingLimitPerHost,
 		"POLLING_PARSING_ERROR_LIMIT":            o.pollingParsingErrorLimit,
 		"POLLING_SCHEDULER":                      o.pollingScheduler,
-		"MEDIA_PROXY_HTTP_CLIENT_TIMEOUT":        o.mediaProxyHTTPClientTimeout,
+		"MEDIA_PROXY_HTTP_CLIENT_TIMEOUT":        int(o.mediaProxyHTTPClientTimeout.Seconds()),
 		"MEDIA_PROXY_RESOURCE_TYPES":             o.mediaProxyResourceTypes,
 		"MEDIA_PROXY_MODE":                       o.mediaProxyMode,
 		"MEDIA_PROXY_PRIVATE_KEY":                mediaProxyPrivateKeyValue,

+ 2 - 2
internal/config/parser.go

@@ -161,7 +161,7 @@ func (p *parser) parseLines(lines []string) (err error) {
 		case "SCHEDULER_ROUND_ROBIN_MAX_INTERVAL":
 			p.opts.schedulerRoundRobinMaxInterval = parseInterval(value, time.Minute, defaultSchedulerRoundRobinMaxInterval)
 		case "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT":
-			p.opts.mediaProxyHTTPClientTimeout = parseInt(value, defaultMediaProxyHTTPClientTimeout)
+			p.opts.mediaProxyHTTPClientTimeout = parseInterval(value, time.Second, defaultMediaProxyHTTPClientTimeout)
 		case "MEDIA_PROXY_MODE":
 			p.opts.mediaProxyMode = parseString(value, defaultMediaProxyMode)
 		case "MEDIA_PROXY_RESOURCE_TYPES":
@@ -206,7 +206,7 @@ func (p *parser) parseLines(lines []string) (err error) {
 		case "DISABLE_LOCAL_AUTH":
 			p.opts.disableLocalAuth = parseBool(value, defaultDisableLocalAuth)
 		case "HTTP_CLIENT_TIMEOUT":
-			p.opts.httpClientTimeout = parseInt(value, defaultHTTPClientTimeout)
+			p.opts.httpClientTimeout = parseInterval(value, time.Second, defaultHTTPClientTimeout)
 		case "HTTP_CLIENT_MAX_BODY_SIZE":
 			p.opts.httpClientMaxBodySize = int64(parseInt(value, defaultHTTPClientMaxBodySize) * 1024 * 1024)
 		case "HTTP_CLIENT_PROXY":

+ 4 - 4
internal/reader/fetcher/request_builder.go

@@ -18,14 +18,14 @@ import (
 )
 
 const (
-	defaultHTTPClientTimeout = 20
+	defaultHTTPClientTimeout = 20 * time.Second
 	defaultAcceptHeader      = "application/xml, application/atom+xml, application/rss+xml, application/rdf+xml, application/feed+json, text/html, */*;q=0.9"
 )
 
 type RequestBuilder struct {
 	headers            http.Header
 	clientProxyURL     *url.URL
-	clientTimeout      int
+	clientTimeout      time.Duration
 	useClientProxy     bool
 	withoutRedirects   bool
 	ignoreTLSErrors    bool
@@ -104,7 +104,7 @@ func (r *RequestBuilder) WithCustomFeedProxyURL(proxyURL string) *RequestBuilder
 	return r
 }
 
-func (r *RequestBuilder) WithTimeout(timeout int) *RequestBuilder {
+func (r *RequestBuilder) WithTimeout(timeout time.Duration) *RequestBuilder {
 	r.clientTimeout = timeout
 	return r
 }
@@ -185,7 +185,7 @@ func (r *RequestBuilder) ExecuteRequest(requestURL string) (*http.Response, erro
 	}
 
 	client := &http.Client{
-		Timeout: time.Duration(r.clientTimeout) * time.Second,
+		Timeout: r.clientTimeout,
 	}
 
 	if r.withoutRedirects {

+ 4 - 5
internal/reader/fetcher/request_builder_test.go

@@ -232,9 +232,9 @@ func TestRequestBuilder_CustomAcceptHeaderNotOverridden(t *testing.T) {
 
 func TestRequestBuilder_WithTimeout(t *testing.T) {
 	builder := NewRequestBuilder()
-	builder = builder.WithTimeout(30)
+	builder = builder.WithTimeout(30 * time.Second)
 
-	if builder.clientTimeout != 30 {
+	if builder.clientTimeout != 30*time.Second {
 		t.Errorf("Expected timeout to be 30, got %d", builder.clientTimeout)
 	}
 }
@@ -382,9 +382,8 @@ func TestRequestBuilder_ChainedMethods(t *testing.T) {
 		WithUserAgent("TestAgent/1.0", "DefaultAgent/1.0").
 		WithCookie("test=value").
 		WithETag("etag123").
-		WithTimeout(10).
+		WithTimeout(10 * time.Second).
 		ExecuteRequest(server.URL)
-
 	if err != nil {
 		t.Fatalf("Expected no error, got %v", err)
 	}
@@ -409,7 +408,7 @@ func TestRequestBuilder_TimeoutConfiguration(t *testing.T) {
 
 	builder := NewRequestBuilder()
 	start := time.Now()
-	_, err := builder.WithTimeout(1).ExecuteRequest(server.URL)
+	_, err := builder.WithTimeout(1 * time.Second).ExecuteRequest(server.URL)
 	duration := time.Since(start)
 
 	if err == nil {