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:
parent
4af12a4129
commit
7060ecc163
4 changed files with 63 additions and 23 deletions
|
@ -26,12 +26,12 @@ func runScheduler(store *storage.Storage, pool *worker.Pool) {
|
||||||
|
|
||||||
go cleanupScheduler(
|
go cleanupScheduler(
|
||||||
store,
|
store,
|
||||||
config.Opts.CleanupFrequencyHours(),
|
config.Opts.CleanupFrequency(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSize, errorLimit, limitPerHost int) {
|
func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency time.Duration, batchSize, errorLimit, limitPerHost int) {
|
||||||
for range time.Tick(time.Duration(frequency) * time.Minute) {
|
for range time.Tick(frequency) {
|
||||||
// Generate a batch of feeds for any user that has feeds to refresh.
|
// Generate a batch of feeds for any user that has feeds to refresh.
|
||||||
batchBuilder := store.NewBatchBuilder()
|
batchBuilder := store.NewBatchBuilder()
|
||||||
batchBuilder.WithBatchSize(batchSize)
|
batchBuilder.WithBatchSize(batchSize)
|
||||||
|
@ -49,8 +49,8 @@ func feedScheduler(store *storage.Storage, pool *worker.Pool, frequency, batchSi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanupScheduler(store *storage.Storage, frequency int) {
|
func cleanupScheduler(store *storage.Storage, frequency time.Duration) {
|
||||||
for range time.Tick(time.Duration(frequency) * time.Hour) {
|
for range time.Tick(frequency) {
|
||||||
runCleanupTasks(store)
|
runCleanupTasks(store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -589,12 +589,22 @@ func TestDefaultCleanupFrequencyHoursValue(t *testing.T) {
|
||||||
t.Fatalf(`Parsing failure: %v`, err)
|
t.Fatalf(`Parsing failure: %v`, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := defaultCleanupFrequencyHours
|
expected := defaultCleanupFrequency
|
||||||
result := opts.CleanupFrequencyHours()
|
result := opts.CleanupFrequency()
|
||||||
|
|
||||||
if result != expected {
|
if result != expected {
|
||||||
t.Fatalf(`Unexpected CLEANUP_FREQUENCY_HOURS value, got %v instead of %v`, 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) {
|
func TestCleanupFrequencyHours(t *testing.T) {
|
||||||
|
@ -608,12 +618,22 @@ func TestCleanupFrequencyHours(t *testing.T) {
|
||||||
t.Fatalf(`Parsing failure: %v`, err)
|
t.Fatalf(`Parsing failure: %v`, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := 42
|
expected := 42 * time.Hour
|
||||||
result := opts.CleanupFrequencyHours()
|
result := opts.CleanupFrequency()
|
||||||
|
|
||||||
if result != expected {
|
if result != expected {
|
||||||
t.Fatalf(`Unexpected CLEANUP_FREQUENCY_HOURS value, got %v instead of %v`, 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) {
|
func TestDefaultCleanupArchiveReadDaysValue(t *testing.T) {
|
||||||
|
@ -737,6 +757,16 @@ func TestDefaultPollingFrequencyValue(t *testing.T) {
|
||||||
if result != expected {
|
if result != expected {
|
||||||
t.Fatalf(`Unexpected POLLING_FREQUENCY value, got %v instead of %v`, 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) {
|
func TestPollingFrequency(t *testing.T) {
|
||||||
|
@ -749,12 +779,22 @@ func TestPollingFrequency(t *testing.T) {
|
||||||
t.Fatalf(`Parsing failure: %v`, err)
|
t.Fatalf(`Parsing failure: %v`, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := 42
|
expected := 42 * time.Minute
|
||||||
result := opts.PollingFrequency()
|
result := opts.PollingFrequency()
|
||||||
|
|
||||||
if result != expected {
|
if result != expected {
|
||||||
t.Fatalf(`Unexpected POLLING_FREQUENCY value, got %v instead of %v`, 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) {
|
func TestDefaultForceRefreshInterval(t *testing.T) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ const (
|
||||||
defaultRootURL = "http://localhost"
|
defaultRootURL = "http://localhost"
|
||||||
defaultBasePath = ""
|
defaultBasePath = ""
|
||||||
defaultWorkerPoolSize = 16
|
defaultWorkerPoolSize = 16
|
||||||
defaultPollingFrequency = 60
|
defaultPollingFrequency = 60 * time.Minute
|
||||||
defaultForceRefreshInterval = 30 * time.Second
|
defaultForceRefreshInterval = 30 * time.Second
|
||||||
defaultBatchSize = 100
|
defaultBatchSize = 100
|
||||||
defaultPollingScheduler = "round_robin"
|
defaultPollingScheduler = "round_robin"
|
||||||
|
@ -47,7 +47,7 @@ const (
|
||||||
defaultCertFile = ""
|
defaultCertFile = ""
|
||||||
defaultKeyFile = ""
|
defaultKeyFile = ""
|
||||||
defaultCertDomain = ""
|
defaultCertDomain = ""
|
||||||
defaultCleanupFrequencyHours = 24
|
defaultCleanupFrequency = 24 * time.Hour
|
||||||
defaultCleanupArchiveReadDays = 60
|
defaultCleanupArchiveReadDays = 60
|
||||||
defaultCleanupArchiveUnreadDays = 180
|
defaultCleanupArchiveUnreadDays = 180
|
||||||
defaultCleanupArchiveBatchSize = 10000
|
defaultCleanupArchiveBatchSize = 10000
|
||||||
|
@ -125,7 +125,7 @@ type options struct {
|
||||||
certFile string
|
certFile string
|
||||||
certDomain string
|
certDomain string
|
||||||
certKeyFile string
|
certKeyFile string
|
||||||
cleanupFrequencyHours int
|
cleanupFrequencyInterval time.Duration
|
||||||
cleanupArchiveReadDays int
|
cleanupArchiveReadDays int
|
||||||
cleanupArchiveUnreadDays int
|
cleanupArchiveUnreadDays int
|
||||||
cleanupArchiveBatchSize int
|
cleanupArchiveBatchSize int
|
||||||
|
@ -137,7 +137,7 @@ type options struct {
|
||||||
schedulerEntryFrequencyFactor int
|
schedulerEntryFrequencyFactor int
|
||||||
schedulerRoundRobinMinInterval time.Duration
|
schedulerRoundRobinMinInterval time.Duration
|
||||||
schedulerRoundRobinMaxInterval time.Duration
|
schedulerRoundRobinMaxInterval time.Duration
|
||||||
pollingFrequency int
|
pollingFrequency time.Duration
|
||||||
pollingLimitPerHost int
|
pollingLimitPerHost int
|
||||||
pollingParsingErrorLimit int
|
pollingParsingErrorLimit int
|
||||||
pollingScheduler string
|
pollingScheduler string
|
||||||
|
@ -209,7 +209,7 @@ func NewOptions() *options {
|
||||||
certFile: defaultCertFile,
|
certFile: defaultCertFile,
|
||||||
certDomain: defaultCertDomain,
|
certDomain: defaultCertDomain,
|
||||||
certKeyFile: defaultKeyFile,
|
certKeyFile: defaultKeyFile,
|
||||||
cleanupFrequencyHours: defaultCleanupFrequencyHours,
|
cleanupFrequencyInterval: defaultCleanupFrequency,
|
||||||
cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
|
cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
|
||||||
cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
|
cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
|
||||||
cleanupArchiveBatchSize: defaultCleanupArchiveBatchSize,
|
cleanupArchiveBatchSize: defaultCleanupArchiveBatchSize,
|
||||||
|
@ -361,9 +361,9 @@ func (o *options) CertDomain() string {
|
||||||
return o.certDomain
|
return o.certDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanupFrequencyHours returns the interval in hours for cleanup jobs.
|
// CleanupFrequencyHours returns the interval for cleanup jobs.
|
||||||
func (o *options) CleanupFrequencyHours() int {
|
func (o *options) CleanupFrequency() time.Duration {
|
||||||
return o.cleanupFrequencyHours
|
return o.cleanupFrequencyInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanupArchiveReadDays returns the number of days after which marking read items as removed.
|
// 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.
|
// PollingFrequency returns the interval to refresh feeds in the background.
|
||||||
func (o *options) PollingFrequency() int {
|
func (o *options) PollingFrequency() time.Duration {
|
||||||
return o.pollingFrequency
|
return o.pollingFrequency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,10 +721,10 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
|
||||||
"BATCH_SIZE": o.batchSize,
|
"BATCH_SIZE": o.batchSize,
|
||||||
"CERT_DOMAIN": o.certDomain,
|
"CERT_DOMAIN": o.certDomain,
|
||||||
"CERT_FILE": o.certFile,
|
"CERT_FILE": o.certFile,
|
||||||
|
"CLEANUP_FREQUENCY_HOURS": int(o.cleanupFrequencyInterval.Hours()),
|
||||||
"CLEANUP_ARCHIVE_BATCH_SIZE": o.cleanupArchiveBatchSize,
|
"CLEANUP_ARCHIVE_BATCH_SIZE": o.cleanupArchiveBatchSize,
|
||||||
"CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
|
"CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
|
||||||
"CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
|
"CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
|
||||||
"CLEANUP_FREQUENCY_HOURS": o.cleanupFrequencyHours,
|
|
||||||
"CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
|
"CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
|
||||||
"CREATE_ADMIN": o.createAdmin,
|
"CREATE_ADMIN": o.createAdmin,
|
||||||
"DATABASE_CONNECTION_LIFETIME": o.databaseConnectionLifetime,
|
"DATABASE_CONNECTION_LIFETIME": o.databaseConnectionLifetime,
|
||||||
|
@ -770,7 +770,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
|
||||||
"OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
|
"OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
|
||||||
"DISABLE_LOCAL_AUTH": o.disableLocalAuth,
|
"DISABLE_LOCAL_AUTH": o.disableLocalAuth,
|
||||||
"FORCE_REFRESH_INTERVAL": int(o.forceRefreshInterval.Seconds()),
|
"FORCE_REFRESH_INTERVAL": int(o.forceRefreshInterval.Seconds()),
|
||||||
"POLLING_FREQUENCY": o.pollingFrequency,
|
"POLLING_FREQUENCY": int(o.pollingFrequency.Minutes()),
|
||||||
"POLLING_LIMIT_PER_HOST": o.pollingLimitPerHost,
|
"POLLING_LIMIT_PER_HOST": o.pollingLimitPerHost,
|
||||||
"POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
|
"POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
|
||||||
"POLLING_SCHEDULER": o.pollingScheduler,
|
"POLLING_SCHEDULER": o.pollingScheduler,
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (p *parser) parseLines(lines []string) (err error) {
|
||||||
case "CERT_DOMAIN":
|
case "CERT_DOMAIN":
|
||||||
p.opts.certDomain = parseString(value, defaultCertDomain)
|
p.opts.certDomain = parseString(value, defaultCertDomain)
|
||||||
case "CLEANUP_FREQUENCY_HOURS":
|
case "CLEANUP_FREQUENCY_HOURS":
|
||||||
p.opts.cleanupFrequencyHours = parseInt(value, defaultCleanupFrequencyHours)
|
p.opts.cleanupFrequencyInterval = parseInterval(value, time.Hour, defaultCleanupFrequency)
|
||||||
case "CLEANUP_ARCHIVE_READ_DAYS":
|
case "CLEANUP_ARCHIVE_READ_DAYS":
|
||||||
p.opts.cleanupArchiveReadDays = parseInt(value, defaultCleanupArchiveReadDays)
|
p.opts.cleanupArchiveReadDays = parseInt(value, defaultCleanupArchiveReadDays)
|
||||||
case "CLEANUP_ARCHIVE_UNREAD_DAYS":
|
case "CLEANUP_ARCHIVE_UNREAD_DAYS":
|
||||||
|
@ -143,7 +143,7 @@ func (p *parser) parseLines(lines []string) (err error) {
|
||||||
case "BATCH_SIZE":
|
case "BATCH_SIZE":
|
||||||
p.opts.batchSize = parseInt(value, defaultBatchSize)
|
p.opts.batchSize = parseInt(value, defaultBatchSize)
|
||||||
case "POLLING_FREQUENCY":
|
case "POLLING_FREQUENCY":
|
||||||
p.opts.pollingFrequency = parseInt(value, defaultPollingFrequency)
|
p.opts.pollingFrequency = parseInterval(value, time.Minute, defaultPollingFrequency)
|
||||||
case "POLLING_LIMIT_PER_HOST":
|
case "POLLING_LIMIT_PER_HOST":
|
||||||
p.opts.pollingLimitPerHost = parseInt(value, 0)
|
p.opts.pollingLimitPerHost = parseInt(value, 0)
|
||||||
case "POLLING_PARSING_ERROR_LIMIT":
|
case "POLLING_PARSING_ERROR_LIMIT":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue