From 61f8da707c8031f531aeabdaa4a14f9756e7ba35 Mon Sep 17 00:00:00 2001 From: kim Date: Mon, 24 Mar 2025 21:34:36 +0000 Subject: [PATCH] fix test-identified timeline cache package issues --- internal/cache/timeline/status.go | 62 +++++++++++------------- internal/id/page.go | 22 ++++++++- internal/processing/timeline/timeline.go | 3 +- 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/internal/cache/timeline/status.go b/internal/cache/timeline/status.go index dd8820bea..a53ae43ba 100644 --- a/internal/cache/timeline/status.go +++ b/internal/cache/timeline/status.go @@ -392,7 +392,7 @@ func (t *StatusTimeline) Load( var filtered []*StatusMeta // 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 // we can repeatedly update it. @@ -661,31 +661,11 @@ func (t *StatusTimeline) prepare( panic("nil prepare fn") } - // Iterate the given StatusMeta objects for pre-prepared frontend - // models, otherwise storing as unprepared for further processing. - apiStatuses := make([]*apimodel.Status, len(meta)) + // Iterate the given StatusMeta objects for pre-prepared + // frontend models, otherwise attempting to prepare them. + apiStatuses := make([]*apimodel.Status, 0, len(meta)) unprepared := make([]*StatusMeta, 0, len(meta)) - for i, 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] + for _, meta := range meta { if meta.loaded == nil { // We failed loading this @@ -693,23 +673,35 @@ func (t *StatusTimeline) prepare( continue } - // Prepare the provided status to frontend. - apiStatus, err := prepareAPI(meta.loaded) - if err != nil { - log.Errorf(ctx, "error preparing status %s: %v", meta.loaded.URI, err) - continue + if meta.prepared == nil { + var err error + + // Prepare the provided status to frontend. + 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 // / 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 - // status meta types into timeline cache. - t.cache.Insert(unprepared...) + if len(unprepared) != 0 { + // Re-insert all (previously) unprepared + // status meta types into timeline cache. + t.cache.Insert(unprepared...) + } return apiStatuses, nil } diff --git a/internal/id/page.go b/internal/id/page.go index 36ce5a065..b43ccd4e2 100644 --- a/internal/id/page.go +++ b/internal/id/page.go @@ -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 . + package id import ( "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) { if page == nil { // unpaged diff --git a/internal/processing/timeline/timeline.go b/internal/processing/timeline/timeline.go index ce1d33f50..deedcb76d 100644 --- a/internal/processing/timeline/timeline.go +++ b/internal/processing/timeline/timeline.go @@ -108,12 +108,13 @@ func (p *Processor) getStatusTimeline( } // Ensure we have valid - // input paging data. + // input paging cursor. id.ValidatePage(page) // ... apiStatuses, lo, hi, err := timeline.Load(ctx, + // ... page, // ...