Browse Source

refactor(http): use time.Duration for refresh interval

It's not clear which units of time used for refresh interval.
Convert to time.Duration for clarity.
gudvinr 7 months ago
parent
commit
c6536e8d90

+ 11 - 1
internal/config/config_test.go

@@ -784,12 +784,22 @@ func TestForceRefreshInterval(t *testing.T) {
 		t.Fatalf(`Parsing failure: %v`, err)
 	}
 
-	expected := 42
+	expected := 42 * time.Second
 	result := opts.ForceRefreshInterval()
 
 	if result != expected {
 		t.Fatalf(`Unexpected FORCE_REFRESH_INTERVAL value, got %v instead of %v`, result, expected)
 	}
+
+	sorted := opts.SortedOptions(false)
+	i := slices.IndexFunc(sorted, func(opt *option) bool {
+		return opt.Key == "FORCE_REFRESH_INTERVAL"
+	})
+
+	expectedSerialized := 42
+	if got := sorted[i].Value; got != expectedSerialized {
+		t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
+	}
 }
 
 func TestDefaultBatchSizeValue(t *testing.T) {

+ 4 - 4
internal/config/options.go

@@ -29,7 +29,7 @@ const (
 	defaultBasePath                           = ""
 	defaultWorkerPoolSize                     = 16
 	defaultPollingFrequency                   = 60
-	defaultForceRefreshInterval               = 30
+	defaultForceRefreshInterval               = 30 * time.Second
 	defaultBatchSize                          = 100
 	defaultPollingScheduler                   = "round_robin"
 	defaultSchedulerEntryFrequencyMinInterval = 5 * time.Minute
@@ -130,7 +130,7 @@ type options struct {
 	cleanupArchiveUnreadDays           int
 	cleanupArchiveBatchSize            int
 	cleanupRemoveSessionsDays          int
-	forceRefreshInterval               int
+	forceRefreshInterval               time.Duration
 	batchSize                          int
 	schedulerEntryFrequencyMinInterval time.Duration
 	schedulerEntryFrequencyMaxInterval time.Duration
@@ -392,7 +392,7 @@ func (o *options) WorkerPoolSize() int {
 }
 
 // ForceRefreshInterval returns the force refresh interval
-func (o *options) ForceRefreshInterval() int {
+func (o *options) ForceRefreshInterval() time.Duration {
 	return o.forceRefreshInterval
 }
 
@@ -769,7 +769,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
 		"OAUTH2_REDIRECT_URL":                    o.oauth2RedirectURL,
 		"OAUTH2_USER_CREATION":                   o.oauth2UserCreationAllowed,
 		"DISABLE_LOCAL_AUTH":                     o.disableLocalAuth,
-		"FORCE_REFRESH_INTERVAL":                 o.forceRefreshInterval,
+		"FORCE_REFRESH_INTERVAL":                 int(o.forceRefreshInterval.Seconds()),
 		"POLLING_FREQUENCY":                      o.pollingFrequency,
 		"POLLING_LIMIT_PER_HOST":                 o.pollingLimitPerHost,
 		"POLLING_PARSING_ERROR_LIMIT":            o.pollingParsingErrorLimit,

+ 1 - 1
internal/config/parser.go

@@ -139,7 +139,7 @@ func (p *parser) parseLines(lines []string) (err error) {
 		case "WORKER_POOL_SIZE":
 			p.opts.workerPoolSize = parseInt(value, defaultWorkerPoolSize)
 		case "FORCE_REFRESH_INTERVAL":
-			p.opts.forceRefreshInterval = parseInt(value, defaultForceRefreshInterval)
+			p.opts.forceRefreshInterval = parseInterval(value, time.Second, defaultForceRefreshInterval)
 		case "BATCH_SIZE":
 			p.opts.batchSize = parseInt(value, defaultBatchSize)
 		case "POLLING_FREQUENCY":

+ 4 - 3
internal/http/request/context.go

@@ -6,6 +6,7 @@ package request // import "miniflux.app/v2/internal/http/request"
 import (
 	"net/http"
 	"strconv"
+	"time"
 
 	"miniflux.app/v2/internal/model"
 )
@@ -135,13 +136,13 @@ func FlashErrorMessage(r *http.Request) string {
 }
 
 // LastForceRefresh returns the last force refresh timestamp.
-func LastForceRefresh(r *http.Request) int64 {
+func LastForceRefresh(r *http.Request) time.Time {
 	jsonStringValue := getContextStringValue(r, LastForceRefreshContextKey)
 	timestamp, err := strconv.ParseInt(jsonStringValue, 10, 64)
 	if err != nil {
-		return 0
+		return time.Time{}
 	}
-	return timestamp
+	return time.Unix(timestamp, 0)
 }
 
 // ClientIP returns the client IP address stored in the context.

+ 3 - 3
internal/ui/category_refresh.go

@@ -32,9 +32,9 @@ func (h *handler) refreshCategory(w http.ResponseWriter, r *http.Request) int64
 	sess := session.New(h.store, request.SessionID(r))
 
 	// Avoid accidental and excessive refreshes.
-	if time.Now().UTC().Unix()-request.LastForceRefresh(r) < int64(config.Opts.ForceRefreshInterval())*60 {
-		time := config.Opts.ForceRefreshInterval()
-		sess.NewFlashErrorMessage(printer.Plural("alert.too_many_feeds_refresh", time, time))
+	if time.Since(request.LastForceRefresh(r)) < config.Opts.ForceRefreshInterval() {
+		seconds := int(config.Opts.ForceRefreshInterval().Seconds())
+		sess.NewFlashErrorMessage(printer.Plural("alert.too_many_feeds_refresh", seconds, seconds))
 	} else {
 		userID := request.UserID(r)
 		// We allow the end-user to force refresh all its feeds in this category

+ 3 - 3
internal/ui/feed_refresh.go

@@ -37,9 +37,9 @@ func (h *handler) refreshAllFeeds(w http.ResponseWriter, r *http.Request) {
 	sess := session.New(h.store, request.SessionID(r))
 
 	// Avoid accidental and excessive refreshes.
-	if time.Now().UTC().Unix()-request.LastForceRefresh(r) < int64(config.Opts.ForceRefreshInterval())*60 {
-		time := config.Opts.ForceRefreshInterval()
-		sess.NewFlashErrorMessage(printer.Plural("alert.too_many_feeds_refresh", time, time))
+	if time.Since(request.LastForceRefresh(r)) < config.Opts.ForceRefreshInterval() {
+		seconds := int(config.Opts.ForceRefreshInterval().Seconds())
+		sess.NewFlashErrorMessage(printer.Plural("alert.too_many_feeds_refresh", seconds, seconds))
 	} else {
 		userID := request.UserID(r)
 		// We allow the end-user to force refresh all its feeds