From b6de7144e09e7ce8b02f73795b98a6a466794c2f Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Fri, 1 Sep 2023 21:39:39 +0200 Subject: [PATCH] feat(feeds): clear feed cache (#1071) --- internal/database/feed_cache.go | 2 +- internal/feed/service.go | 16 +++++++++++ internal/http/feed.go | 22 ++++++++++++++++ web/src/api/APIClient.ts | 1 + web/src/screens/settings/Feed.tsx | 44 +++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 1 deletion(-) diff --git a/internal/database/feed_cache.go b/internal/database/feed_cache.go index 747b855..5d0fb6c 100644 --- a/internal/database/feed_cache.go +++ b/internal/database/feed_cache.go @@ -216,7 +216,7 @@ func (r *FeedCacheRepo) DeleteBucket(ctx context.Context, bucket string) error { } if rows == 0 { - return errors.Wrap(err, "error no rows affected") + r.log.Warn().Msgf("no rows affected for delete of bucket: %s", bucket) } return nil diff --git a/internal/feed/service.go b/internal/feed/service.go index a99125a..38a6900 100644 --- a/internal/feed/service.go +++ b/internal/feed/service.go @@ -33,6 +33,7 @@ type Service interface { Test(ctx context.Context, feed *domain.Feed) error ToggleEnabled(ctx context.Context, id int, enabled bool) error Delete(ctx context.Context, id int) error + DeleteFeedCache(ctx context.Context, id int) error GetLastRunData(ctx context.Context, id int) (string, error) Start() error @@ -122,6 +123,21 @@ func (s *service) Delete(ctx context.Context, id int) error { return s.delete(ctx, id) } +func (s *service) DeleteFeedCache(ctx context.Context, id int) error { + feed, err := s.repo.FindByID(ctx, id) + if err != nil { + s.log.Error().Err(err).Msgf("could not find feed by id: %d", id) + return err + } + + if err := s.cacheRepo.DeleteBucket(ctx, feed.Name); err != nil { + s.log.Error().Err(err).Msgf("could not clear feed cache: %d", id) + return err + } + + return nil +} + func (s *service) ToggleEnabled(ctx context.Context, id int, enabled bool) error { return s.toggleEnabled(ctx, id, enabled) } diff --git a/internal/http/feed.go b/internal/http/feed.go index 8e831b1..48e0c63 100644 --- a/internal/http/feed.go +++ b/internal/http/feed.go @@ -19,6 +19,7 @@ type feedService interface { Store(ctx context.Context, feed *domain.Feed) error Update(ctx context.Context, feed *domain.Feed) error Delete(ctx context.Context, id int) error + DeleteFeedCache(ctx context.Context, id int) error ToggleEnabled(ctx context.Context, id int, enabled bool) error Test(ctx context.Context, feed *domain.Feed) error GetLastRunData(ctx context.Context, id int) (string, error) @@ -44,6 +45,7 @@ func (h feedHandler) Routes(r chi.Router) { r.Route("/{feedID}", func(r chi.Router) { r.Put("/", h.update) r.Delete("/", h.delete) + r.Delete("/cache", h.deleteCache) r.Patch("/enabled", h.toggleEnabled) r.Get("/latest", h.latestRun) }) @@ -168,6 +170,26 @@ func (h feedHandler) delete(w http.ResponseWriter, r *http.Request) { h.encoder.StatusResponse(w, http.StatusNoContent, nil) } +func (h feedHandler) deleteCache(w http.ResponseWriter, r *http.Request) { + var ( + ctx = r.Context() + filterID = chi.URLParam(r, "feedID") + ) + + id, err := strconv.Atoi(filterID) + if err != nil { + h.encoder.Error(w, err) + return + } + + if err := h.service.DeleteFeedCache(ctx, id); err != nil { + h.encoder.Error(w, err) + return + } + + h.encoder.StatusResponse(w, http.StatusNoContent, nil) +} + func (h feedHandler) latestRun(w http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/web/src/api/APIClient.ts b/web/src/api/APIClient.ts index bbbd195..1c61c60 100644 --- a/web/src/api/APIClient.ts +++ b/web/src/api/APIClient.ts @@ -131,6 +131,7 @@ export const APIClient = { toggleEnable: (id: number, enabled: boolean) => appClient.Patch(`api/feeds/${id}/enabled`, { enabled }), update: (feed: Feed) => appClient.Put(`api/feeds/${feed.id}`, feed), delete: (id: number) => appClient.Delete(`api/feeds/${id}`), + deleteCache: (id: number) => appClient.Delete(`api/feeds/${id}/cache`), test: (feed: Feed) => appClient.Post("api/feeds/test", feed) }, indexers: { diff --git a/web/src/screens/settings/Feed.tsx b/web/src/screens/settings/Feed.tsx index c4d24ce..fcc10e7 100644 --- a/web/src/screens/settings/Feed.tsx +++ b/web/src/screens/settings/Feed.tsx @@ -23,6 +23,7 @@ import { DeleteModal } from "@components/modals"; import { FeedUpdateForm } from "@forms/settings/FeedForms"; import { EmptySimple } from "@components/emptystates"; import { ImplementationBadges } from "./Indexer"; +import {ArrowPathIcon} from "@heroicons/react/24/solid"; export const feedKeys = { all: ["feeds"] as const, @@ -230,10 +231,13 @@ const FeedItemDropdown = ({ toggleUpdate }: FeedItemDropdownProps) => { const cancelModalButtonRef = useRef(null); + const cancelCacheModalButtonRef = useRef(null); const queryClient = useQueryClient(); const [deleteModalIsOpen, toggleDeleteModal] = useToggle(false); + const [deleteCacheModalIsOpen, toggleDeleteCacheModal] = useToggle(false); + const deleteMutation = useMutation({ mutationFn: (id: number) => APIClient.feeds.delete(id), onSuccess: () => { @@ -244,6 +248,13 @@ const FeedItemDropdown = ({ } }); + const deleteCacheMutation = useMutation({ + mutationFn: (id: number) => APIClient.feeds.deleteCache(id), + onSuccess: () => { + toast.custom((t) => ); + } + }); + return ( + { + deleteCacheMutation.mutate(feed.id); + }} + title={`Remove feed cache: ${feed.name}`} + text="Are you sure you want to remove the feed cache? This action cannot be undone." + /> +
{({ active }) => (