mirror of
https://github.com/miniflux/v2.git
synced 2025-08-01 17:38:37 +00:00
Add alternative scheduler based on the number of entries
This commit is contained in:
parent
25d4b9fc0c
commit
cead85b165
12 changed files with 423 additions and 119 deletions
|
@ -6,8 +6,11 @@ package model // import "miniflux.app/model"
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"miniflux.app/config"
|
||||
"miniflux.app/http/client"
|
||||
)
|
||||
|
||||
|
@ -19,6 +22,7 @@ type Feed struct {
|
|||
SiteURL string `json:"site_url"`
|
||||
Title string `json:"title"`
|
||||
CheckedAt time.Time `json:"checked_at"`
|
||||
NextCheckAt time.Time `json:"next_check_at"`
|
||||
EtagHeader string `json:"etag_header"`
|
||||
LastModifiedHeader string `json:"last_modified_header"`
|
||||
ParsingErrorMsg string `json:"parsing_error_message"`
|
||||
|
@ -37,6 +41,11 @@ type Feed struct {
|
|||
ReadCount int `json:"-"`
|
||||
}
|
||||
|
||||
const (
|
||||
// SchedulerEntryCountBased represnets the name of the scheduler based on entry counts.
|
||||
SchedulerEntryCountBased = "entry_count_based"
|
||||
)
|
||||
|
||||
func (f *Feed) String() string {
|
||||
return fmt.Sprintf("ID=%d, UserID=%d, FeedURL=%s, SiteURL=%s, Title=%s, Category={%s}",
|
||||
f.ID,
|
||||
|
@ -91,5 +100,27 @@ func (f *Feed) CheckedNow() {
|
|||
}
|
||||
}
|
||||
|
||||
// ScheduleNextCheck set "next_check_at" of a feed based on the scheduler selected from the configuration.
|
||||
func (f *Feed) ScheduleNextCheck(weeklyCount int) {
|
||||
var nextCheckAt time.Time
|
||||
switch strings.ToLower(config.Opts.PollingScheduler()) {
|
||||
case SchedulerEntryCountBased:
|
||||
var intervalMinutes int
|
||||
if weeklyCount == 0 {
|
||||
intervalMinutes = config.Opts.SchedulerCountBasedMaxInterval()
|
||||
} else {
|
||||
intervalMinutes = int(math.Round(float64(7*24*60) / float64(weeklyCount)))
|
||||
}
|
||||
intervalMinutes = int(math.Min(float64(intervalMinutes), float64(config.Opts.SchedulerCountBasedMaxInterval())))
|
||||
intervalMinutes = int(math.Max(float64(intervalMinutes), float64(config.Opts.SchedulerCountBasedMinInterval())))
|
||||
nextCheckAt = time.Now().Add(time.Minute * time.Duration(intervalMinutes))
|
||||
default:
|
||||
// round robin
|
||||
// omit the interval because they are same for all feeds.
|
||||
nextCheckAt = time.Now()
|
||||
}
|
||||
f.NextCheckAt = nextCheckAt
|
||||
}
|
||||
|
||||
// Feeds is a list of feed
|
||||
type Feeds []*Feed
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
package model // import "miniflux.app/model"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"miniflux.app/config"
|
||||
"miniflux.app/http/client"
|
||||
)
|
||||
|
||||
|
@ -107,3 +111,74 @@ func TestFeedCheckedNow(t *testing.T) {
|
|||
t.Error(`The checked date must be set`)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFeedScheduleNextCheckDefault(t *testing.T) {
|
||||
var err error
|
||||
parser := config.NewParser()
|
||||
config.Opts, err = parser.ParseEnvironmentVariables()
|
||||
if err != nil {
|
||||
t.Fatalf(`Parsing failure: %v`, err)
|
||||
}
|
||||
|
||||
feed := &Feed{}
|
||||
weeklyCount := 10
|
||||
feed.ScheduleNextCheck(weeklyCount)
|
||||
|
||||
if feed.NextCheckAt.IsZero() {
|
||||
t.Error(`The next_check_at must be set`)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFeedScheduleNextCheckEntryCountBasedMaxInterval(t *testing.T) {
|
||||
maxInterval := 5
|
||||
minInterval := 1
|
||||
os.Clearenv()
|
||||
os.Setenv("POLLING_SCHEDULER", "entry_count_based")
|
||||
os.Setenv("SCHEDULER_ENTRY_COUNT_BASED_MAX_INTERVAL", fmt.Sprintf("%d", maxInterval))
|
||||
os.Setenv("SCHEDULER_ENTRY_COUNT_BASED_MIN_INTERVAL", fmt.Sprintf("%d", minInterval))
|
||||
|
||||
var err error
|
||||
parser := config.NewParser()
|
||||
config.Opts, err = parser.ParseEnvironmentVariables()
|
||||
if err != nil {
|
||||
t.Fatalf(`Parsing failure: %v`, err)
|
||||
}
|
||||
feed := &Feed{}
|
||||
weeklyCount := maxInterval * 100
|
||||
feed.ScheduleNextCheck(weeklyCount)
|
||||
|
||||
if feed.NextCheckAt.IsZero() {
|
||||
t.Error(`The next_check_at must be set`)
|
||||
}
|
||||
|
||||
if feed.NextCheckAt.After(time.Now().Add(time.Minute * time.Duration(maxInterval))) {
|
||||
t.Error(`The next_check_at should not be after the now + max interval`)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFeedScheduleNextCheckEntryCountBasedMinInterval(t *testing.T) {
|
||||
maxInterval := 500
|
||||
minInterval := 100
|
||||
os.Clearenv()
|
||||
os.Setenv("POLLING_SCHEDULER", "entry_count_based")
|
||||
os.Setenv("SCHEDULER_ENTRY_COUNT_BASED_MAX_INTERVAL", fmt.Sprintf("%d", maxInterval))
|
||||
os.Setenv("SCHEDULER_ENTRY_COUNT_BASED_MIN_INTERVAL", fmt.Sprintf("%d", minInterval))
|
||||
|
||||
var err error
|
||||
parser := config.NewParser()
|
||||
config.Opts, err = parser.ParseEnvironmentVariables()
|
||||
if err != nil {
|
||||
t.Fatalf(`Parsing failure: %v`, err)
|
||||
}
|
||||
feed := &Feed{}
|
||||
weeklyCount := minInterval / 2
|
||||
feed.ScheduleNextCheck(weeklyCount)
|
||||
|
||||
if feed.NextCheckAt.IsZero() {
|
||||
t.Error(`The next_check_at must be set`)
|
||||
}
|
||||
|
||||
if feed.NextCheckAt.Before(time.Now().Add(time.Minute * time.Duration(minInterval))) {
|
||||
t.Error(`The next_check_at should not be before the now + min interval`)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue