Auto-reindex channel on page visit if stale
GET /channels/{id} now fires a background _index_channel_task if the
channel hasn't been crawled in the last hour. The frontend refetches
channel + videos 8s after page load to pick up the updated data.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -546,6 +546,7 @@ def bulk_channel_action(
|
|||||||
@router.get("/{channel_id}", response_model=ChannelOut)
|
@router.get("/{channel_id}", response_model=ChannelOut)
|
||||||
def get_channel(
|
def get_channel(
|
||||||
channel_id: int,
|
channel_id: int,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
current_user: User = Depends(get_current_user),
|
current_user: User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
@@ -576,6 +577,16 @@ def get_channel(
|
|||||||
).mappings().first()
|
).mappings().first()
|
||||||
if not row:
|
if not row:
|
||||||
raise HTTPException(status_code=404, detail="Channel not found")
|
raise HTTPException(status_code=404, detail="Channel not found")
|
||||||
|
|
||||||
|
# Re-index in the background if stale (not crawled in the last hour)
|
||||||
|
crawled_at = row.get("crawled_at")
|
||||||
|
stale = (
|
||||||
|
crawled_at is None
|
||||||
|
or (datetime.utcnow() - crawled_at).total_seconds() > 3600
|
||||||
|
)
|
||||||
|
if stale:
|
||||||
|
background_tasks.add_task(_index_channel_task, channel_id, current_user.id)
|
||||||
|
|
||||||
return ChannelOut(**dict(row))
|
return ChannelOut(**dict(row))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useMemo } from "react";
|
import { useState, useMemo, useEffect, useRef } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { getChannel, getChannelVideos, followChannel, unfollowChannel, indexChannel, downloadChannel } from "../api";
|
import { getChannel, getChannelVideos, followChannel, unfollowChannel, indexChannel, downloadChannel } from "../api";
|
||||||
@@ -41,6 +41,18 @@ export default function ChannelPage() {
|
|||||||
queryFn: () => getChannelVideos(id).then((r) => r.data),
|
queryFn: () => getChannelVideos(id).then((r) => r.data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Refetch after the background re-index has had time to run
|
||||||
|
const refetchedRef = useRef(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id || refetchedRef.current) return;
|
||||||
|
refetchedRef.current = true;
|
||||||
|
const t = setTimeout(() => {
|
||||||
|
qc.invalidateQueries({ queryKey: ["channel", id] });
|
||||||
|
qc.invalidateQueries({ queryKey: ["channel-videos", id] });
|
||||||
|
}, 8000);
|
||||||
|
return () => clearTimeout(t);
|
||||||
|
}, [id, qc]);
|
||||||
|
|
||||||
const followMut = useMutation({
|
const followMut = useMutation({
|
||||||
mutationFn: () =>
|
mutationFn: () =>
|
||||||
channel?.status === "followed" ? unfollowChannel(id) : followChannel(id),
|
channel?.status === "followed" ? unfollowChannel(id) : followChannel(id),
|
||||||
|
|||||||
Reference in New Issue
Block a user