federate status deletes properly

This commit is contained in:
tsmethurst 2021-06-04 16:35:58 +02:00
commit 197ef03ead
19 changed files with 154 additions and 143 deletions

View file

@ -19,6 +19,8 @@
package timeline
import (
"fmt"
"strings"
"sync"
"github.com/sirupsen/logrus"
@ -66,6 +68,10 @@ type Manager interface {
GetOldestIndexedID(timelineAccountID string) (string, error)
// PrepareXFromTop prepares limit n amount of posts, based on their indexed representations, from the top of the index.
PrepareXFromTop(timelineAccountID string, limit int) error
// WipeStatusFromTimeline completely removes a status and from the index and prepared posts of the given account ID
WipeStatusFromTimeline(timelineAccountID string, statusID string) error
// WipeStatusFromAllTimelines removes the status from the index and prepared posts of all timelines
WipeStatusFromAllTimelines(statusID string) error
}
// NewManager returns a new timeline manager with the given database, typeconverter, config, and log.
@ -172,6 +178,37 @@ func (m *manager) PrepareXFromTop(timelineAccountID string, limit int) error {
return t.PrepareXFromTop(limit)
}
func (m *manager) WipeStatusFromTimeline(timelineAccountID string, statusID string) error {
t := m.getOrCreateTimeline(timelineAccountID)
return t.Remove(statusID)
}
func (m *manager) WipeStatusFromAllTimelines(statusID string) error {
errors := []string{}
m.accountTimelines.Range(func(k interface{}, i interface{}) bool {
t, ok := i.(Timeline)
if !ok {
panic("couldn't parse entry as Timeline, this should never happen so panic")
}
if err := t.Remove(statusID); err != nil {
errors = append(errors, err.Error())
}
return false
})
var err error
if len(errors) > 0 {
err = fmt.Errorf("one or more errors removing status %s from all timelines: %s", statusID, strings.Join(errors, ";"))
}
return err
}
func (m *manager) getOrCreateTimeline(timelineAccountID string) Timeline {
var t Timeline
i, ok := m.accountTimelines.Load(timelineAccountID)

View file

@ -334,27 +334,31 @@ func (t *timeline) Remove(statusID string) error {
t.Lock()
defer t.Unlock()
// remove the entry from the post index
for e := t.postIndex.data.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*postIndexEntry)
if !ok {
return errors.New("Remove: could not parse e as a postIndexEntry")
}
if entry.statusID == statusID {
t.postIndex.data.Remove(e)
break // bail once we found and removed it
if t.postIndex != nil && t.postIndex.data != nil {
// remove the entry from the post index
for e := t.postIndex.data.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*postIndexEntry)
if !ok {
return errors.New("Remove: could not parse e as a postIndexEntry")
}
if entry.statusID == statusID {
t.postIndex.data.Remove(e)
break // bail once we found and removed it
}
}
}
// remove the entry from prepared posts
for e := t.preparedPosts.data.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*preparedPostsEntry)
if !ok {
return errors.New("Remove: could not parse e as a preparedPostsEntry")
}
if entry.statusID == statusID {
t.preparedPosts.data.Remove(e)
break // bail once we found and removed it
if t.preparedPosts != nil && t.preparedPosts.data != nil {
for e := t.preparedPosts.data.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*preparedPostsEntry)
if !ok {
return errors.New("Remove: could not parse e as a preparedPostsEntry")
}
if entry.statusID == statusID {
t.preparedPosts.data.Remove(e)
break // bail once we found and removed it
}
}
}