1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-26 18:21:01 +00:00

refactor(cli): use time.Duration for scheduler frequency

Polling frequency is undocumented so it's not exacly clear what units were.
This commit is contained in:
gudvinr 2025-08-18 23:10:18 +03:00 committed by Frédéric Guillot
parent 4af12a4129
commit 7060ecc163
4 changed files with 63 additions and 23 deletions

View file

@ -26,12 +26,12 @@ func runScheduler(store *storage.Storage, pool *worker.Pool) {
go cleanupScheduler(
store,
config.Opts.CleanupFrequencyHours(),
config.Opts.CleanupFrequency(),
)
}
func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSize, errorLimit, limitPerHost int) {
for range time.Tick(time.Duration(frequency) * time.Minute) {
func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency time.Duration, batchSize, errorLimit, limitPerHost int) {
for range time.Tick(frequency) {
// Generate a batch of feeds for any user that has feeds to refresh.
batchBuilder := store.NewBatchBuilder()
batchBuilder.WithBatchSize(batchSize)
@ -49,8 +49,8 @@ func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSi
}
}
func cleanupScheduler(store *storage.Storage, frequency int) {
for range time.Tick(time.Duration(frequency) * time.Hour) {
func cleanupScheduler(store *storage.Storage, frequency time.Duration) {
for range time.Tick(frequency) {
runCleanupTasks(store)
}
}

View file

@ -589,12 +589,22 @@ func TestDefaultCleanupFrequencyHoursValue(t *testing.T) {
t.Fatalf(`Parsing failure: %v`, err)
}
expected := defaultCleanupFrequencyHours
result := opts.CleanupFrequencyHours()
expected := defaultCleanupFrequency
result := opts.CleanupFrequency()
if result != expected {
t.Fatalf(`Unexpected CLEANUP_FREQUENCY_HOURS value, got %v instead of %v`, result, expected)
}
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "CLEANUP_FREQUENCY_HOURS"
})
expectedSerialized := int(defaultCleanupFrequency / time.Hour)
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
}
func TestCleanupFrequencyHours(t *testing.T) {
@ -608,12 +618,22 @@ func TestCleanupFrequencyHours(t *testing.T) {
t.Fatalf(`Parsing failure: %v`, err)
}
expected := 42
result := opts.CleanupFrequencyHours()
expected := 42 * time.Hour
result := opts.CleanupFrequency()
if result != expected {
t.Fatalf(`Unexpected CLEANUP_FREQUENCY_HOURS value, got %v instead of %v`, result, expected)
}
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "CLEANUP_FREQUENCY_HOURS"
})
expectedSerialized := 42
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
}
func TestDefaultCleanupArchiveReadDaysValue(t *testing.T) {
@ -737,6 +757,16 @@ func TestDefaultPollingFrequencyValue(t *testing.T) {
if result != expected {
t.Fatalf(`Unexpected POLLING_FREQUENCY value, got %v instead of %v`, result, expected)
}
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "POLLING_FREQUENCY"
})
expectedSerialized := int(defaultPollingFrequency / time.Minute)
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
}
func TestPollingFrequency(t *testing.T) {
@ -749,12 +779,22 @@ func TestPollingFrequency(t *testing.T) {
t.Fatalf(`Parsing failure: %v`, err)
}
expected := 42
expected := 42 * time.Minute
result := opts.PollingFrequency()
if result != expected {
t.Fatalf(`Unexpected POLLING_FREQUENCY value, got %v instead of %v`, result, expected)
}
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "POLLING_FREQUENCY"
})
expectedSerialized := 42
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
}
func TestDefaultForceRefreshInterval(t *testing.T) {

View file

@ -28,7 +28,7 @@ const (
defaultRootURL = "http://localhost"
defaultBasePath = ""
defaultWorkerPoolSize = 16
defaultPollingFrequency = 60
defaultPollingFrequency = 60 * time.Minute
defaultForceRefreshInterval = 30 * time.Second
defaultBatchSize = 100
defaultPollingScheduler = "round_robin"
@ -47,7 +47,7 @@ const (
defaultCertFile = ""
defaultKeyFile = ""
defaultCertDomain = ""
defaultCleanupFrequencyHours = 24
defaultCleanupFrequency = 24 * time.Hour
defaultCleanupArchiveReadDays = 60
defaultCleanupArchiveUnreadDays = 180
defaultCleanupArchiveBatchSize = 10000
@ -125,7 +125,7 @@ type options struct {
certFile string
certDomain string
certKeyFile string
cleanupFrequencyHours int
cleanupFrequencyInterval time.Duration
cleanupArchiveReadDays int
cleanupArchiveUnreadDays int
cleanupArchiveBatchSize int
@ -137,7 +137,7 @@ type options struct {
schedulerEntryFrequencyFactor int
schedulerRoundRobinMinInterval time.Duration
schedulerRoundRobinMaxInterval time.Duration
pollingFrequency int
pollingFrequency time.Duration
pollingLimitPerHost int
pollingParsingErrorLimit int
pollingScheduler string
@ -209,7 +209,7 @@ func NewOptions() *options {
certFile: defaultCertFile,
certDomain: defaultCertDomain,
certKeyFile: defaultKeyFile,
cleanupFrequencyHours: defaultCleanupFrequencyHours,
cleanupFrequencyInterval: defaultCleanupFrequency,
cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
cleanupArchiveBatchSize: defaultCleanupArchiveBatchSize,
@ -361,9 +361,9 @@ func (o *options) CertDomain() string {
return o.certDomain
}
// CleanupFrequencyHours returns the interval in hours for cleanup jobs.
func (o *options) CleanupFrequencyHours() int {
return o.cleanupFrequencyHours
// CleanupFrequencyHours returns the interval for cleanup jobs.
func (o *options) CleanupFrequency() time.Duration {
return o.cleanupFrequencyInterval
}
// CleanupArchiveReadDays returns the number of days after which marking read items as removed.
@ -402,7 +402,7 @@ func (o *options) BatchSize() int {
}
// PollingFrequency returns the interval to refresh feeds in the background.
func (o *options) PollingFrequency() int {
func (o *options) PollingFrequency() time.Duration {
return o.pollingFrequency
}
@ -721,10 +721,10 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
"BATCH_SIZE": o.batchSize,
"CERT_DOMAIN": o.certDomain,
"CERT_FILE": o.certFile,
"CLEANUP_FREQUENCY_HOURS": int(o.cleanupFrequencyInterval.Hours()),
"CLEANUP_ARCHIVE_BATCH_SIZE": o.cleanupArchiveBatchSize,
"CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
"CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
"CLEANUP_FREQUENCY_HOURS": o.cleanupFrequencyHours,
"CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
"CREATE_ADMIN": o.createAdmin,
"DATABASE_CONNECTION_LIFETIME": o.databaseConnectionLifetime,
@ -770,7 +770,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
"OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
"DISABLE_LOCAL_AUTH": o.disableLocalAuth,
"FORCE_REFRESH_INTERVAL": int(o.forceRefreshInterval.Seconds()),
"POLLING_FREQUENCY": o.pollingFrequency,
"POLLING_FREQUENCY": int(o.pollingFrequency.Minutes()),
"POLLING_LIMIT_PER_HOST": o.pollingLimitPerHost,
"POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
"POLLING_SCHEDULER": o.pollingScheduler,

View file

@ -127,7 +127,7 @@ func (p *parser) parseLines(lines []string) (err error) {
case "CERT_DOMAIN":
p.opts.certDomain = parseString(value, defaultCertDomain)
case "CLEANUP_FREQUENCY_HOURS":
p.opts.cleanupFrequencyHours = parseInt(value, defaultCleanupFrequencyHours)
p.opts.cleanupFrequencyInterval = parseInterval(value, time.Hour, defaultCleanupFrequency)
case "CLEANUP_ARCHIVE_READ_DAYS":
p.opts.cleanupArchiveReadDays = parseInt(value, defaultCleanupArchiveReadDays)
case "CLEANUP_ARCHIVE_UNREAD_DAYS":
@ -143,7 +143,7 @@ func (p *parser) parseLines(lines []string) (err error) {
case "BATCH_SIZE":
p.opts.batchSize = parseInt(value, defaultBatchSize)
case "POLLING_FREQUENCY":
p.opts.pollingFrequency = parseInt(value, defaultPollingFrequency)
p.opts.pollingFrequency = parseInterval(value, time.Minute, defaultPollingFrequency)
case "POLLING_LIMIT_PER_HOST":
p.opts.pollingLimitPerHost = parseInt(value, 0)
case "POLLING_PARSING_ERROR_LIMIT":