mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-18 09:37:28 -06:00
[performance] add statusfilter cache to cache calculated status filtering results (#4303)
this adds another 'filter' type cache, similar to the visibility and mute caches, to cache the results of status filtering checks. for the moment this keeps all the check calls themselves within the frontend typeconversion code, but i may move this out of the typeconverter in a future PR (also removing the ErrHideStatus means of propagating a hidden status). also tweaks some of the cache invalidation hooks to not make unnecessary calls. Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4303 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
This commit is contained in:
parent
8b0ea56027
commit
4f2aa792b3
50 changed files with 1017 additions and 544 deletions
|
|
@ -74,11 +74,12 @@ func (p *Processor) BookmarksGet(ctx context.Context, requestingAccount *gtsmode
|
|||
}
|
||||
|
||||
// Convert the status.
|
||||
item, err := p.converter.StatusToAPIStatus(ctx, status, requestingAccount, gtsmodel.FilterContextNone, nil)
|
||||
item, err := p.converter.StatusToAPIStatus(ctx, status, requestingAccount, gtsmodel.FilterContextNone)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error converting bookmarked status to api: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,15 +96,9 @@ func (p *Processor) StatusesGet(
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
filters, err := p.state.DB.GetFiltersByAccountID(ctx, requestingAccount.ID)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("couldn't retrieve filters for account %s: %w", requestingAccount.ID, err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
for _, s := range filtered {
|
||||
// Convert filtered statuses to API statuses.
|
||||
item, err := p.converter.StatusToAPIStatus(ctx, s, requestingAccount, gtsmodel.FilterContextAccount, filters)
|
||||
item, err := p.converter.StatusToAPIStatus(ctx, s, requestingAccount, gtsmodel.FilterContextAccount)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error convering to api status: %v", err)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import (
|
|||
apimodel "code.superseriousbusiness.org/gotosocial/internal/api/model"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/db"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/federation/dereferencing"
|
||||
statusfilter "code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/log"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
)
|
||||
|
||||
// GetOwnStatus fetches the given status with ID,
|
||||
|
|
@ -214,7 +214,6 @@ func (p *Processor) GetAPIStatus(
|
|||
target,
|
||||
requester,
|
||||
gtsmodel.FilterContextNone,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
err := gtserror.Newf("error converting: %w", err)
|
||||
|
|
@ -235,7 +234,6 @@ func (p *Processor) GetVisibleAPIStatuses(
|
|||
requester *gtsmodel.Account,
|
||||
statuses []*gtsmodel.Status,
|
||||
filterCtx gtsmodel.FilterContext,
|
||||
filters []*gtsmodel.Filter,
|
||||
) []apimodel.Status {
|
||||
|
||||
// Start new log entry with
|
||||
|
|
@ -278,9 +276,8 @@ func (p *Processor) GetVisibleAPIStatuses(
|
|||
status,
|
||||
requester,
|
||||
filterCtx,
|
||||
filters,
|
||||
)
|
||||
if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
|
||||
if err != nil && !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
l.Errorf("error converting: %v", err)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import (
|
|||
|
||||
apimodel "code.superseriousbusiness.org/gotosocial/internal/api/model"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/db"
|
||||
statusfilter "code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/id"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/log"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
|
|||
if err != nil {
|
||||
// If the conversation's last status matched a hide filter, skip it.
|
||||
// If there was another kind of error, log that and skip it anyway.
|
||||
if !errors.Is(err, statusfilter.ErrHideStatus) {
|
||||
if !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
log.Errorf(ctx,
|
||||
"error converting conversation %s to API representation for account %s: %v",
|
||||
status.ID,
|
||||
|
|
|
|||
|
|
@ -28,12 +28,19 @@ import (
|
|||
"code.superseriousbusiness.org/gotosocial/internal/gtscontext"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/log"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/processing/stream"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/state"
|
||||
)
|
||||
|
||||
type Processor struct{ state *state.State }
|
||||
type Processor struct {
|
||||
state *state.State
|
||||
stream *stream.Processor
|
||||
}
|
||||
|
||||
func New(state *state.State) *Processor { return &Processor{state} }
|
||||
func New(state *state.State, stream *stream.Processor) *Processor {
|
||||
return &Processor{state, stream}
|
||||
}
|
||||
|
||||
// CheckFilterExists calls .GetFilter() with a barebones context to not
|
||||
// fetch any sub-models, and not returning the result. this functionally
|
||||
|
|
@ -160,6 +167,27 @@ func (p *Processor) GetFilterKeyword(
|
|||
return keyword, filter, nil
|
||||
}
|
||||
|
||||
// OnFilterChanged ...
|
||||
func (p *Processor) OnFilterChanged(ctx context.Context, requester *gtsmodel.Account) {
|
||||
|
||||
// Get list of list IDs created by this requesting account.
|
||||
listIDs, err := p.state.DB.GetListIDsByAccountID(ctx, requester.ID)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error getting account '%s' lists: %v", requester.Username, err)
|
||||
}
|
||||
|
||||
// Unprepare this requester's home timeline.
|
||||
p.state.Caches.Timelines.Home.Unprepare(requester.ID)
|
||||
|
||||
// Unprepare list timelines.
|
||||
for _, id := range listIDs {
|
||||
p.state.Caches.Timelines.List.Unprepare(id)
|
||||
}
|
||||
|
||||
// Send filter changed event for account.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
}
|
||||
|
||||
// FromAPIContexts converts a slice of frontend API model FilterContext types to our internal FilterContexts bit field.
|
||||
func FromAPIContexts(apiContexts []apimodel.FilterContext) (gtsmodel.FilterContexts, gtserror.WithCode) {
|
||||
var contexts gtsmodel.FilterContexts
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ func (p *Processor) Create(ctx context.Context, requester *gtsmodel.Account, for
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
// Return as converted frontend filter keyword model.
|
||||
return typeutils.FilterKeywordToAPIFilterV1(filter, filterKeyword), nil
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ func (p *Processor) Delete(
|
|||
}
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package v1
|
|||
|
||||
import (
|
||||
"code.superseriousbusiness.org/gotosocial/internal/processing/filters/common"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/processing/stream"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/state"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
)
|
||||
|
|
@ -30,15 +29,13 @@ type Processor struct {
|
|||
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
stream *stream.Processor
|
||||
}
|
||||
|
||||
func New(state *state.State, converter *typeutils.Converter, common *common.Processor, stream *stream.Processor) Processor {
|
||||
func New(state *state.State, converter *typeutils.Converter, common *common.Processor) Processor {
|
||||
return Processor{
|
||||
c: common,
|
||||
|
||||
state: state,
|
||||
converter: converter,
|
||||
stream: stream,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ func (p *Processor) Update(
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
// Return as converted frontend filter keyword model.
|
||||
return typeutils.FilterKeywordToAPIFilterV1(filter, filterKeyword), nil
|
||||
|
|
|
|||
|
|
@ -34,13 +34,13 @@ import (
|
|||
|
||||
// Create a new filter for the given account, using the provided parameters.
|
||||
// These params should have already been validated by the time they reach this function.
|
||||
func (p *Processor) Create(ctx context.Context, account *gtsmodel.Account, form *apimodel.FilterCreateRequestV2) (*apimodel.FilterV2, gtserror.WithCode) {
|
||||
func (p *Processor) Create(ctx context.Context, requester *gtsmodel.Account, form *apimodel.FilterCreateRequestV2) (*apimodel.FilterV2, gtserror.WithCode) {
|
||||
var errWithCode gtserror.WithCode
|
||||
|
||||
// Create new filter model.
|
||||
filter := >smodel.Filter{
|
||||
ID: id.NewULID(),
|
||||
AccountID: account.ID,
|
||||
AccountID: requester.ID,
|
||||
Title: form.Title,
|
||||
}
|
||||
|
||||
|
|
@ -104,8 +104,8 @@ func (p *Processor) Create(ctx context.Context, account *gtsmodel.Account, form
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Send a filters changed event.
|
||||
p.stream.FiltersChanged(ctx, account)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
// Return as converted frontend filter model.
|
||||
return typeutils.FilterToAPIFilterV2(filter), nil
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ func (p *Processor) Delete(
|
|||
return gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package v2
|
|||
|
||||
import (
|
||||
"code.superseriousbusiness.org/gotosocial/internal/processing/filters/common"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/processing/stream"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/state"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
)
|
||||
|
|
@ -30,15 +29,13 @@ type Processor struct {
|
|||
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
stream *stream.Processor
|
||||
}
|
||||
|
||||
func New(state *state.State, converter *typeutils.Converter, common *common.Processor, stream *stream.Processor) Processor {
|
||||
func New(state *state.State, converter *typeutils.Converter, common *common.Processor) Processor {
|
||||
return Processor{
|
||||
c: common,
|
||||
|
||||
state: state,
|
||||
converter: converter,
|
||||
stream: stream,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ func (p *Processor) KeywordCreate(ctx context.Context, requester *gtsmodel.Accou
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return typeutils.FilterKeywordToAPIFilterKeyword(filterKeyword), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ func (p *Processor) KeywordDelete(
|
|||
return gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ func (p *Processor) KeywordUpdate(
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return typeutils.FilterKeywordToAPIFilterKeyword(filterKeyword), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ func (p *Processor) StatusCreate(ctx context.Context, requester *gtsmodel.Accoun
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return typeutils.FilterStatusToAPIFilterStatus(filterStatus), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ func (p *Processor) StatusDelete(
|
|||
return gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ func (p *Processor) Update(
|
|||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Stream a filters changed event to WS.
|
||||
p.stream.FiltersChanged(ctx, requester)
|
||||
// Handle filter change side-effects.
|
||||
p.c.OnFilterChanged(ctx, requester)
|
||||
|
||||
// Return as converted frontend filter model.
|
||||
return typeutils.FilterToAPIFilterV2(filter), nil
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func NewProcessor(
|
|||
processor.account = account.New(&common, state, converter, mediaManager, federator, visFilter, parseMentionFunc)
|
||||
processor.media = media.New(&common, state, converter, federator, mediaManager, federator.TransportController())
|
||||
processor.stream = stream.New(state, oauthServer)
|
||||
filterCommon := filterCommon.New(state)
|
||||
filterCommon := filterCommon.New(state, &processor.stream)
|
||||
|
||||
// Instantiate the rest of the sub
|
||||
// processors + pin them to this struct.
|
||||
|
|
@ -234,8 +234,8 @@ func NewProcessor(
|
|||
processor.application = application.New(state, converter)
|
||||
processor.conversations = conversations.New(state, converter, visFilter, muteFilter)
|
||||
processor.fedi = fedi.New(state, &common, converter, federator, visFilter)
|
||||
processor.filtersv1 = filtersv1.New(state, converter, filterCommon, &processor.stream)
|
||||
processor.filtersv2 = filtersv2.New(state, converter, filterCommon, &processor.stream)
|
||||
processor.filtersv1 = filtersv1.New(state, converter, filterCommon)
|
||||
processor.filtersv2 = filtersv2.New(state, converter, filterCommon)
|
||||
processor.interactionRequests = interactionrequests.New(&common, state, converter)
|
||||
processor.list = list.New(state, converter)
|
||||
processor.markers = markers.New(state, converter)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ func (p *Processor) packageStatuses(
|
|||
continue
|
||||
}
|
||||
|
||||
apiStatus, err := p.converter.StatusToAPIStatus(ctx, status, requestingAccount, gtsmodel.FilterContextNone, nil)
|
||||
apiStatus, err := p.converter.StatusToAPIStatus(ctx, status, requestingAccount, gtsmodel.FilterContextNone)
|
||||
if err != nil {
|
||||
log.Debugf(ctx, "skipping status %s because it couldn't be converted to its api representation: %s", status.ID, err)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -275,20 +275,6 @@ func (p *Processor) ContextGet(
|
|||
requester *gtsmodel.Account,
|
||||
targetStatusID string,
|
||||
) (*apimodel.ThreadContext, gtserror.WithCode) {
|
||||
// Retrieve filters as they affect
|
||||
// what should be shown to requester.
|
||||
filters, err := p.state.DB.GetFiltersByAccountID(
|
||||
ctx, // Populate filters.
|
||||
requester.ID,
|
||||
)
|
||||
if err != nil {
|
||||
err = gtserror.Newf(
|
||||
"couldn't retrieve filters for account %s: %w",
|
||||
requester.ID, err,
|
||||
)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Retrieve the full thread context.
|
||||
threadContext, errWithCode := p.contextGet(ctx,
|
||||
requester,
|
||||
|
|
@ -305,7 +291,6 @@ func (p *Processor) ContextGet(
|
|||
requester,
|
||||
threadContext.ancestors,
|
||||
gtsmodel.FilterContextThread,
|
||||
filters,
|
||||
)
|
||||
|
||||
// Convert and filter the thread context descendants
|
||||
|
|
@ -313,7 +298,6 @@ func (p *Processor) ContextGet(
|
|||
requester,
|
||||
threadContext.descendants,
|
||||
gtsmodel.FilterContextThread,
|
||||
filters,
|
||||
)
|
||||
|
||||
return &apiContext, nil
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (suite *StatusUpdateTestSuite) TestStreamNotification() {
|
|||
suite.NoError(errWithCode)
|
||||
|
||||
editedStatus := suite.testStatuses["remote_account_1_status_1"]
|
||||
apiStatus, err := typeutils.NewConverter(&suite.state).StatusToAPIStatus(suite.T().Context(), editedStatus, account, gtsmodel.FilterContextNotifications, nil)
|
||||
apiStatus, err := typeutils.NewConverter(&suite.state).StatusToAPIStatus(suite.T().Context(), editedStatus, account, gtsmodel.FilterContextNotifications)
|
||||
suite.NoError(err)
|
||||
|
||||
suite.streamProcessor.StatusUpdate(suite.T().Context(), account, apiStatus, stream.TimelineHome)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ func (p *Processor) FavedTimelineGet(ctx context.Context, authed *apiutil.Auth,
|
|||
continue
|
||||
}
|
||||
|
||||
apiStatus, err := p.converter.StatusToAPIStatus(ctx, s, authed.Account, gtsmodel.FilterContextNone, nil)
|
||||
apiStatus, err := p.converter.StatusToAPIStatus(ctx, s, authed.Account, gtsmodel.FilterContextNone)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error convering to api status: %v", err)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ import (
|
|||
apimodel "code.superseriousbusiness.org/gotosocial/internal/api/model"
|
||||
apiutil "code.superseriousbusiness.org/gotosocial/internal/api/util"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/db"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/log"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/paging"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
|
|
@ -59,12 +59,6 @@ func (p *Processor) NotificationsGet(
|
|||
return util.EmptyPageableResponse(), nil
|
||||
}
|
||||
|
||||
filters, err := p.state.DB.GetFiltersByAccountID(ctx, requester.ID)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("error getting account %s filters: %w", requester.ID, err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
var (
|
||||
items = make([]interface{}, 0, count)
|
||||
|
||||
|
|
@ -115,9 +109,9 @@ func (p *Processor) NotificationsGet(
|
|||
}
|
||||
}
|
||||
|
||||
item, err := p.converter.NotificationToAPINotification(ctx, n, filters)
|
||||
item, err := p.converter.NotificationToAPINotification(ctx, n, true)
|
||||
if err != nil {
|
||||
if !errors.Is(err, status.ErrHideStatus) {
|
||||
if !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
log.Debugf(ctx, "skipping notification %s because it couldn't be converted to its api representation: %s", n.ID, err)
|
||||
}
|
||||
continue
|
||||
|
|
@ -160,7 +154,7 @@ func (p *Processor) NotificationGet(ctx context.Context, account *gtsmodel.Accou
|
|||
// or mute checking for a notification directly
|
||||
// fetched by ID. only from timelines etc.
|
||||
|
||||
apiNotif, err := p.converter.NotificationToAPINotification(ctx, notif, nil)
|
||||
apiNotif, err := p.converter.NotificationToAPINotification(ctx, notif, false)
|
||||
if err != nil {
|
||||
err := gtserror.Newf("error converting to api model: %w", err)
|
||||
return nil, gtserror.WrapWithCode(http.StatusInternalServerError, err)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ import (
|
|||
|
||||
apimodel "code.superseriousbusiness.org/gotosocial/internal/api/model"
|
||||
timelinepkg "code.superseriousbusiness.org/gotosocial/internal/cache/timeline"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/db"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/filter/mutes"
|
||||
statusfilter "code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/filter/visibility"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
|
|
@ -79,18 +77,6 @@ func (p *Processor) getStatusTimeline(
|
|||
gtserror.WithCode,
|
||||
) {
|
||||
var err error
|
||||
var filters []*gtsmodel.Filter
|
||||
|
||||
if requester != nil {
|
||||
// Fetch all filters relevant for requesting account.
|
||||
filters, err = p.state.DB.GetFiltersByAccountID(ctx,
|
||||
requester.ID,
|
||||
)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
err := gtserror.Newf("error getting account filters: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have valid
|
||||
// input paging cursor.
|
||||
|
|
@ -135,9 +121,8 @@ func (p *Processor) getStatusTimeline(
|
|||
status,
|
||||
requester,
|
||||
filterCtx,
|
||||
filters,
|
||||
)
|
||||
if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
|
||||
if err != nil && !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
return nil, err
|
||||
}
|
||||
return apiStatus, nil
|
||||
|
|
|
|||
|
|
@ -213,7 +213,6 @@ func (suite *FromClientAPITestSuite) statusJSON(
|
|||
status,
|
||||
requestingAccount,
|
||||
gtsmodel.FilterContextNone,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
|
|
@ -345,7 +344,7 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithNotification() {
|
|||
suite.FailNow("timed out waiting for new status notification")
|
||||
}
|
||||
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, nil)
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, false)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
|
@ -2032,7 +2031,7 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithAuthorOnExclusiv
|
|||
suite.FailNow("timed out waiting for new status notification")
|
||||
}
|
||||
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, nil)
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, false)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
|
@ -2217,7 +2216,7 @@ func (suite *FromClientAPITestSuite) TestProcessUpdateStatusInteractedWith() {
|
|||
suite.FailNow("timed out waiting for edited status notification")
|
||||
}
|
||||
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, nil)
|
||||
apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, false)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.superseriousbusiness.org/gotosocial/internal/db"
|
||||
statusfilter "code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtscontext"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/id"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/util"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/util/xslices"
|
||||
)
|
||||
|
|
@ -743,14 +743,9 @@ func (s *Surface) Notify(
|
|||
}
|
||||
}
|
||||
|
||||
filters, err := s.State.DB.GetFiltersByAccountID(ctx, targetAccount.ID)
|
||||
if err != nil {
|
||||
return gtserror.Newf("couldn't retrieve filters for account %s: %w", targetAccount.ID, err)
|
||||
}
|
||||
|
||||
// Convert the notification to frontend API model for streaming / push.
|
||||
apiNotif, err := s.Converter.NotificationToAPINotification(ctx, notif, filters)
|
||||
if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
|
||||
// Convert the notification to frontend API model for streaming / web push.
|
||||
apiNotif, err := s.Converter.NotificationToAPINotification(ctx, notif, true)
|
||||
if err != nil && !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
return gtserror.Newf("error converting notification to api representation: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ import (
|
|||
"errors"
|
||||
|
||||
"code.superseriousbusiness.org/gotosocial/internal/cache/timeline"
|
||||
statusfilter "code.superseriousbusiness.org/gotosocial/internal/filter/status"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtscontext"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/log"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/stream"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/typeutils"
|
||||
"code.superseriousbusiness.org/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
|
|
@ -147,19 +147,10 @@ func (s *Surface) timelineAndNotifyStatusForFollowers(
|
|||
continue
|
||||
}
|
||||
|
||||
// Get relevant filters for this follow's account.
|
||||
// (note the origin account of the follow is receiver of status).
|
||||
filters, err := s.getFilters(ctx, follow.AccountID)
|
||||
if err != nil {
|
||||
log.Error(ctx, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add status to any relevant lists for this follow, if applicable.
|
||||
listTimelined, exclusive, err := s.listTimelineStatusForFollow(ctx,
|
||||
status,
|
||||
follow,
|
||||
filters,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error list timelining status: %v", err)
|
||||
|
|
@ -181,7 +172,6 @@ func (s *Surface) timelineAndNotifyStatusForFollowers(
|
|||
status,
|
||||
stream.TimelineHome,
|
||||
gtsmodel.FilterContextHome,
|
||||
filters,
|
||||
); homeTimelined {
|
||||
|
||||
// If hometimelined, add to list of returned account IDs.
|
||||
|
|
@ -239,7 +229,6 @@ func (s *Surface) listTimelineStatusForFollow(
|
|||
ctx context.Context,
|
||||
status *gtsmodel.Status,
|
||||
follow *gtsmodel.Follow,
|
||||
filters []*gtsmodel.Filter,
|
||||
) (timelined bool, exclusive bool, err error) {
|
||||
|
||||
// Get all lists that contain this given follow.
|
||||
|
|
@ -276,7 +265,6 @@ func (s *Surface) listTimelineStatusForFollow(
|
|||
status,
|
||||
stream.TimelineList+":"+list.ID, // key streamType to this specific list
|
||||
gtsmodel.FilterContextHome,
|
||||
filters,
|
||||
)
|
||||
|
||||
// Update flag based on if timelined.
|
||||
|
|
@ -286,15 +274,6 @@ func (s *Surface) listTimelineStatusForFollow(
|
|||
return timelined, exclusive, nil
|
||||
}
|
||||
|
||||
// getFiltersAndMutes returns an account's filters and mutes.
|
||||
func (s *Surface) getFilters(ctx context.Context, accountID string) ([]*gtsmodel.Filter, error) {
|
||||
filters, err := s.State.DB.GetFiltersByAccountID(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("couldn't retrieve filters for account %s: %w", accountID, err)
|
||||
}
|
||||
return filters, err
|
||||
}
|
||||
|
||||
// listEligible checks if the given status is eligible
|
||||
// for inclusion in the list that that the given listEntry
|
||||
// belongs to, based on the replies policy of the list.
|
||||
|
|
@ -370,7 +349,6 @@ func (s *Surface) timelineStatus(
|
|||
status *gtsmodel.Status,
|
||||
streamType string,
|
||||
filterCtx gtsmodel.FilterContext,
|
||||
filters []*gtsmodel.Filter,
|
||||
) bool {
|
||||
|
||||
// Attempt to convert status to frontend API representation,
|
||||
|
|
@ -379,9 +357,8 @@ func (s *Surface) timelineStatus(
|
|||
status,
|
||||
account,
|
||||
filterCtx,
|
||||
filters,
|
||||
)
|
||||
if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
|
||||
if err != nil && !errors.Is(err, typeutils.ErrHideStatus) {
|
||||
log.Error(ctx, "error converting status %s to frontend: %v", status.URI, err)
|
||||
}
|
||||
|
||||
|
|
@ -425,19 +402,12 @@ func (s *Surface) timelineAndNotifyStatusForTagFollowers(
|
|||
// Insert the status into the home timeline of each tag follower.
|
||||
errs := gtserror.MultiError{}
|
||||
for _, tagFollowerAccount := range tagFollowerAccounts {
|
||||
filters, err := s.getFilters(ctx, tagFollowerAccount.ID)
|
||||
if err != nil {
|
||||
errs.Append(err)
|
||||
continue
|
||||
}
|
||||
|
||||
_ = s.timelineStatus(ctx,
|
||||
s.State.Caches.Timelines.Home.MustGet(tagFollowerAccount.ID),
|
||||
tagFollowerAccount,
|
||||
status,
|
||||
stream.TimelineHome,
|
||||
gtsmodel.FilterContextHome,
|
||||
filters,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -605,19 +575,10 @@ func (s *Surface) timelineStatusUpdateForFollowers(
|
|||
continue
|
||||
}
|
||||
|
||||
// Get relevant filters and mutes for this follow's account.
|
||||
// (note the origin account of the follow is receiver of status).
|
||||
filters, err := s.getFilters(ctx, follow.AccountID)
|
||||
if err != nil {
|
||||
log.Error(ctx, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add status to relevant lists for this follow, if applicable.
|
||||
_, exclusive, err := s.listTimelineStatusUpdateForFollow(ctx,
|
||||
status,
|
||||
follow,
|
||||
filters,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error list timelining status: %v", err)
|
||||
|
|
@ -637,7 +598,6 @@ func (s *Surface) timelineStatusUpdateForFollowers(
|
|||
follow.Account,
|
||||
status,
|
||||
stream.TimelineHome,
|
||||
filters,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error home timelining status: %v", err)
|
||||
|
|
@ -662,7 +622,6 @@ func (s *Surface) listTimelineStatusUpdateForFollow(
|
|||
ctx context.Context,
|
||||
status *gtsmodel.Status,
|
||||
follow *gtsmodel.Follow,
|
||||
filters []*gtsmodel.Filter,
|
||||
) (bool, bool, error) {
|
||||
|
||||
// Get all lists that contain this given follow.
|
||||
|
|
@ -701,7 +660,6 @@ func (s *Surface) listTimelineStatusUpdateForFollow(
|
|||
follow.Account,
|
||||
status,
|
||||
stream.TimelineList+":"+list.ID, // key streamType to this specific list
|
||||
filters,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error adding status to list timeline: %v", err)
|
||||
|
|
@ -724,7 +682,6 @@ func (s *Surface) timelineStreamStatusUpdate(
|
|||
account *gtsmodel.Account,
|
||||
status *gtsmodel.Status,
|
||||
streamType string,
|
||||
filters []*gtsmodel.Filter,
|
||||
) (bool, error) {
|
||||
|
||||
// Convert updated database model to frontend model.
|
||||
|
|
@ -732,14 +689,13 @@ func (s *Surface) timelineStreamStatusUpdate(
|
|||
status,
|
||||
account,
|
||||
gtsmodel.FilterContextHome,
|
||||
filters,
|
||||
)
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
// no issue.
|
||||
|
||||
case errors.Is(err, statusfilter.ErrHideStatus):
|
||||
case errors.Is(err, typeutils.ErrHideStatus):
|
||||
// Don't put this status in the stream.
|
||||
return false, nil
|
||||
|
||||
|
|
@ -774,18 +730,11 @@ func (s *Surface) timelineStatusUpdateForTagFollowers(
|
|||
// Stream the update to the home timeline of each tag follower.
|
||||
errs := gtserror.MultiError{}
|
||||
for _, tagFollowerAccount := range tagFollowerAccounts {
|
||||
filters, err := s.getFilters(ctx, tagFollowerAccount.ID)
|
||||
if err != nil {
|
||||
errs.Append(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := s.timelineStreamStatusUpdate(
|
||||
ctx,
|
||||
tagFollowerAccount,
|
||||
status,
|
||||
stream.TimelineHome,
|
||||
filters,
|
||||
); err != nil {
|
||||
errs.Appendf(
|
||||
"error updating status %s on home timeline for account %s: %w",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue