Improve Fever API performances when marking a feed or group as read
This commit is contained in:
parent
98206059fc
commit
ddfe969d6c
2 changed files with 64 additions and 49 deletions
|
@ -530,81 +530,53 @@ func (c *Controller) handleWriteItems(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
/*
|
||||
mark=? where ? is replaced with feed or group
|
||||
mark=feed
|
||||
as=read
|
||||
id=? where ? is replaced with the id of the feed or group to modify
|
||||
before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
|
||||
*/
|
||||
func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) {
|
||||
userID := request.UserID(r)
|
||||
logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID)
|
||||
|
||||
feedID := request.FormInt64Value(r, "id")
|
||||
before := time.Unix(request.FormInt64Value(r, "before"), 0)
|
||||
|
||||
logger.Debug("[Fever] mark=feed, userID=%d, feedID=%d, before=%v", userID, feedID, before)
|
||||
|
||||
if feedID <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
builder := c.store.NewEntryQueryBuilder(userID)
|
||||
builder.WithStatus(model.EntryStatusUnread)
|
||||
builder.WithFeedID(feedID)
|
||||
|
||||
before := request.FormInt64Value(r, "before")
|
||||
if before > 0 {
|
||||
t := time.Unix(before, 0)
|
||||
builder.BeforeDate(t)
|
||||
}
|
||||
|
||||
entryIDs, err := builder.GetEntryIDs()
|
||||
if err != nil {
|
||||
json.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = c.store.SetEntriesStatus(userID, entryIDs, model.EntryStatusRead)
|
||||
if err != nil {
|
||||
json.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
if err := c.store.MarkFeedAsRead(userID, feedID, before); err != nil {
|
||||
logger.Error("[Fever] MarkFeedAsRead failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
json.OK(w, r, newBaseResponse())
|
||||
}
|
||||
|
||||
/*
|
||||
mark=? where ? is replaced with feed or group
|
||||
mark=group
|
||||
as=read
|
||||
id=? where ? is replaced with the id of the feed or group to modify
|
||||
before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
|
||||
*/
|
||||
func (c *Controller) handleWriteGroups(w http.ResponseWriter, r *http.Request) {
|
||||
userID := request.UserID(r)
|
||||
logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID)
|
||||
|
||||
groupID := request.FormInt64Value(r, "id")
|
||||
before := time.Unix(request.FormInt64Value(r, "before"), 0)
|
||||
|
||||
logger.Debug("[Fever] mark=group, userID=%d, groupID=%d, before=%v", userID, groupID, before)
|
||||
|
||||
if groupID < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
builder := c.store.NewEntryQueryBuilder(userID)
|
||||
builder.WithStatus(model.EntryStatusUnread)
|
||||
builder.WithCategoryID(groupID)
|
||||
|
||||
before := request.FormInt64Value(r, "before")
|
||||
if before > 0 {
|
||||
t := time.Unix(before, 0)
|
||||
builder.BeforeDate(t)
|
||||
}
|
||||
|
||||
entryIDs, err := builder.GetEntryIDs()
|
||||
if err != nil {
|
||||
json.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = c.store.SetEntriesStatus(userID, entryIDs, model.EntryStatusRead)
|
||||
if err != nil {
|
||||
json.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
if err := c.store.MarkCategoryAsRead(userID, groupID, before); err != nil {
|
||||
logger.Error("[Fever] MarkCategoryAsRead failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
json.OK(w, r, newBaseResponse())
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ func (s *Storage) FlushHistory(userID int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarkAllAsRead set all entries with the status "unread" to "read".
|
||||
// MarkAllAsRead updates all user entries to the read status.
|
||||
func (s *Storage) MarkAllAsRead(userID int64) error {
|
||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:MarkAllAsRead] userID=%d", userID))
|
||||
|
||||
|
@ -269,6 +269,49 @@ func (s *Storage) MarkAllAsRead(userID int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarkFeedAsRead updates all feed entries to the read status.
|
||||
func (s *Storage) MarkFeedAsRead(userID, feedID int64, before time.Time) error {
|
||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:MarkFeedAsRead] userID=%d, feedID=%d, before=%v", userID, feedID, before))
|
||||
|
||||
query := `
|
||||
UPDATE entries
|
||||
SET status=$1
|
||||
WHERE user_id=$2 AND feed_id=$3 AND status=$4 AND published_at < $5
|
||||
`
|
||||
|
||||
result, err := s.db.Exec(query, model.EntryStatusRead, userID, feedID, model.EntryStatusUnread, before)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to mark feed entries as read: %v", err)
|
||||
}
|
||||
|
||||
count, _ := result.RowsAffected()
|
||||
logger.Debug("[Storage:MarkFeedAsRead] %d items marked as read", count)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkCategoryAsRead updates all category entries to the read status.
|
||||
func (s *Storage) MarkCategoryAsRead(userID, categoryID int64, before time.Time) error {
|
||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:MarkCategoryAsRead] userID=%d, categoryID=%d, before=%v", userID, categoryID, before))
|
||||
|
||||
query := `
|
||||
UPDATE entries
|
||||
SET status=$1
|
||||
WHERE
|
||||
user_id=$2 AND status=$3 AND published_at < $4 AND feed_id IN (SELECT id FROM feeds WHERE user_id=$2 AND category_id=$5)
|
||||
`
|
||||
|
||||
result, err := s.db.Exec(query, model.EntryStatusRead, userID, model.EntryStatusUnread, before, categoryID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to mark category entries as read: %v", err)
|
||||
}
|
||||
|
||||
count, _ := result.RowsAffected()
|
||||
logger.Debug("[Storage:MarkCategoryAsRead] %d items marked as read", count)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EntryURLExists returns true if an entry with this URL already exists.
|
||||
func (s *Storage) EntryURLExists(userID int64, entryURL string) bool {
|
||||
var result int
|
||||
|
|
Loading…
Reference in a new issue