fix test-identified timeline cache package issues

This commit is contained in:
kim 2025-03-24 21:34:36 +00:00
commit 61f8da707c
3 changed files with 50 additions and 37 deletions

View file

@ -392,7 +392,7 @@ func (t *StatusTimeline) Load(
var filtered []*StatusMeta var filtered []*StatusMeta
// Check whether loaded enough from cache. // Check whether loaded enough from cache.
if need := len(metas) - lim; need > 0 { if need := lim - len(metas); need > 0 {
// Use a copy of current page so // Use a copy of current page so
// we can repeatedly update it. // we can repeatedly update it.
@ -661,31 +661,11 @@ func (t *StatusTimeline) prepare(
panic("nil prepare fn") panic("nil prepare fn")
} }
// Iterate the given StatusMeta objects for pre-prepared frontend // Iterate the given StatusMeta objects for pre-prepared
// models, otherwise storing as unprepared for further processing. // frontend models, otherwise attempting to prepare them.
apiStatuses := make([]*apimodel.Status, len(meta)) apiStatuses := make([]*apimodel.Status, 0, len(meta))
unprepared := make([]*StatusMeta, 0, len(meta)) unprepared := make([]*StatusMeta, 0, len(meta))
for i, meta := range meta { for _, meta := range meta {
apiStatuses[i] = meta.prepared
if meta.prepared == nil {
unprepared = append(unprepared, meta)
}
}
// If there were no unprepared
// StatusMeta objects, then we
// gathered everything we can!
if len(unprepared) == 0 {
return apiStatuses, nil
}
// By this point all status objects should
// be fully populated with loaded models,
// since they are required for filtering.
for i := 0; i < len(unprepared); {
// Get meta at index.
meta := unprepared[i]
if meta.loaded == nil { if meta.loaded == nil {
// We failed loading this // We failed loading this
@ -693,23 +673,35 @@ func (t *StatusTimeline) prepare(
continue continue
} }
// Prepare the provided status to frontend. if meta.prepared == nil {
apiStatus, err := prepareAPI(meta.loaded) var err error
if err != nil {
log.Errorf(ctx, "error preparing status %s: %v", meta.loaded.URI, err) // Prepare the provided status to frontend.
continue meta.prepared, err = prepareAPI(meta.loaded)
if err != nil {
log.Errorf(ctx, "error preparing status %s: %v", meta.loaded.URI, err)
continue
}
// Add this meta to list of unprepared,
// for later re-caching in the timeline.
unprepared = append(unprepared, meta)
} }
if apiStatus != nil { if meta.prepared != nil {
// TODO: we won't need nil check when mutes // TODO: we won't need nil check when mutes
// / filters are moved to appropriate funcs. // / filters are moved to appropriate funcs.
apiStatuses = append(apiStatuses, apiStatus) //
// Add the prepared API model to return slice.
apiStatuses = append(apiStatuses, meta.prepared)
} }
} }
// Re-insert all (previously) unprepared if len(unprepared) != 0 {
// status meta types into timeline cache. // Re-insert all (previously) unprepared
t.cache.Insert(unprepared...) // status meta types into timeline cache.
t.cache.Insert(unprepared...)
}
return apiStatuses, nil return apiStatuses, nil
} }

View file

@ -1,10 +1,30 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package id package id
import ( import (
"github.com/superseriousbusiness/gotosocial/internal/paging" "github.com/superseriousbusiness/gotosocial/internal/paging"
) )
// ValidatePage ... // ValidatePage ensures that passed page has valid paging
// values for the current defined ordering. That is, it
// ensures a valid page *cursor* value, using id.Highest
// or id.Lowest where appropriate when none given.
func ValidatePage(page *paging.Page) { func ValidatePage(page *paging.Page) {
if page == nil { if page == nil {
// unpaged // unpaged

View file

@ -108,12 +108,13 @@ func (p *Processor) getStatusTimeline(
} }
// Ensure we have valid // Ensure we have valid
// input paging data. // input paging cursor.
id.ValidatePage(page) id.ValidatePage(page)
// ... // ...
apiStatuses, lo, hi, err := timeline.Load(ctx, apiStatuses, lo, hi, err := timeline.Load(ctx,
// ...
page, page,
// ... // ...