diff --git a/server/handlers.go b/server/handlers.go index c6cc63c..0bcadfb 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -372,6 +372,9 @@ func SettingsHandler(rw http.ResponseWriter, req *http.Request) { return } if db(req).UpdateSettings(settings) { + if _, ok := settings["refresh_rate"]; ok { + handler(req).refreshRate <- db(req).GetSettingsValueInt64("refresh_rate") + } rw.WriteHeader(http.StatusOK) } else { rw.WriteHeader(http.StatusBadRequest) diff --git a/server/server.go b/server/server.go index c0f32ea..a76306f 100644 --- a/server/server.go +++ b/server/server.go @@ -11,21 +11,23 @@ import ( ) type Handler struct { - Addr string - db *storage.Storage - log *log.Logger - feedQueue chan storage.Feed - queueSize *int32 + Addr string + db *storage.Storage + log *log.Logger + feedQueue chan storage.Feed + queueSize *int32 + refreshRate chan int64 } func New(db *storage.Storage, logger *log.Logger, addr string) *Handler { queueSize := int32(0) return &Handler{ - db: db, - log: logger, - feedQueue: make(chan storage.Feed, 3000), - queueSize: &queueSize, - Addr: addr, + db: db, + log: logger, + feedQueue: make(chan storage.Feed, 3000), + queueSize: &queueSize, + Addr: addr, + refreshRate: make(chan int64), } } @@ -36,7 +38,7 @@ func (h *Handler) Start() { if err != http.ErrServerClosed { h.log.Fatal(err) } -} +} func (h Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { route, vars := getRoute(req) @@ -53,11 +55,11 @@ func (h *Handler) startJobs() { delTicker := time.NewTicker(time.Hour * 24) syncSearchChannel := make(chan bool, 10) - var syncSearchTimer *time.Timer // TODO: should this be atomic? + var syncSearchTimer *time.Timer // TODO: should this be atomic? syncSearch := func() { if syncSearchTimer == nil { - syncSearchTimer = time.AfterFunc(time.Second * 2, func() { + syncSearchTimer = time.AfterFunc(time.Second*2, func() { syncSearchChannel <- true }) } else { @@ -86,9 +88,9 @@ func (h *Handler) startJobs() { h.log.Printf("Failed to search favicon for %s (%s): %s", feed.Link, feed.FeedLink, err) } } - case <- delTicker.C: + case <-delTicker.C: h.db.DeleteOldItems() - case <- syncSearchChannel: + case <-syncSearchChannel: h.db.SyncSearch() } } @@ -103,10 +105,37 @@ func (h *Handler) startJobs() { } go h.db.DeleteOldItems() go h.db.SyncSearch() - //h.fetchAllFeeds() + + go func() { + var refreshTicker *time.Ticker + refreshTick := make(<-chan time.Time) + for { + select { + case <-refreshTick: + h.fetchAllFeeds() + case val := <-h.refreshRate: + if refreshTicker != nil { + refreshTicker.Stop() + if val == 0 { + refreshTick = make(<-chan time.Time) + } + } + if val > 0 { + refreshTicker = time.NewTicker(time.Duration(val) * time.Second) + refreshTick = refreshTicker.C + } + } + } + }() + refreshRate := h.db.GetSettingsValueInt64("refresh_rate") + h.refreshRate <- refreshRate + if refreshRate > 0 { + h.fetchAllFeeds() + } } func (h *Handler) fetchAllFeeds() { + h.log.Print("Refreshing all feeds") for _, feed := range h.db.ListFeeds() { h.fetchFeed(feed) } diff --git a/storage/settings.go b/storage/settings.go index 2c68123..ef545e5 100644 --- a/storage/settings.go +++ b/storage/settings.go @@ -31,6 +31,16 @@ func (s *Storage) GetSettingsValue(key string) interface{} { return valDecoded } +func (s *Storage) GetSettingsValueInt64(key string) int64 { + val := s.GetSettingsValue(key) + if val != nil { + if fval, ok := val.(float64); ok { + return int64(fval) + } + } + return 0 +} + func (s *Storage) GetSettings() map[string]interface{} { result := settingsDefaults() rows, err := s.db.Query(`select key, val from settings;`)