Abort caption requests when they are not in view to tax the server less.
This commit is contained in:
1 parent
a484e55d66
commit
b43ea6c2d3
2 files changed
+23
-12
No files matched your search
@@ -5,8 +5,18 @@ import path from 'path';
|
|||||||
import { getDatasetsRoot } from '@/server/settings';
|
import { getDatasetsRoot } from '@/server/settings';
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
|
let body;
|
||||||
|
try {
|
||||||
|
body = await request.json();
|
||||||
|
} catch {
|
||||||
|
// Client aborted the request before body was fully sent
|
||||||
|
return new NextResponse(null, { status: 499 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.signal.aborted) {
|
||||||
|
return new NextResponse(null, { status: 499 });
|
||||||
|
}
|
||||||
|
|
||||||
const body = await request.json();
|
|
||||||
const { imgPath } = body;
|
const { imgPath } = body;
|
||||||
console.log('Received POST request for caption:', imgPath);
|
console.log('Received POST request for caption:', imgPath);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -28,18 +28,19 @@ const DatasetImageCard: React.FC<DatasetImageCardProps> = ({
|
|||||||
const [isCaptionLoaded, setIsCaptionLoaded] = useState<boolean>(false);
|
const [isCaptionLoaded, setIsCaptionLoaded] = useState<boolean>(false);
|
||||||
const [caption, setCaption] = useState<string>('');
|
const [caption, setCaption] = useState<string>('');
|
||||||
const [savedCaption, setSavedCaption] = useState<string>('');
|
const [savedCaption, setSavedCaption] = useState<string>('');
|
||||||
const isGettingCaption = useRef<boolean>(false);
|
const abortControllerRef = useRef<AbortController | null>(null);
|
||||||
|
|
||||||
const fetchCaption = async () => {
|
const fetchCaption = async () => {
|
||||||
if (isGettingCaption.current || isCaptionLoaded) return;
|
if (isCaptionLoaded) return;
|
||||||
isGettingCaption.current = true;
|
abortControllerRef.current?.abort();
|
||||||
|
const controller = new AbortController();
|
||||||
|
abortControllerRef.current = controller;
|
||||||
apiClient
|
apiClient
|
||||||
.post(`/api/caption/get`, { imgPath: imageUrl })
|
.post(`/api/caption/get`, { imgPath: imageUrl }, { signal: controller.signal })
|
||||||
.then(res => res.data)
|
.then(res => res.data)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('Caption fetched:', data);
|
console.log('Caption fetched:', data);
|
||||||
if (data) {
|
if (data) {
|
||||||
// fix issue where caption could be non string
|
|
||||||
data = `${data}`;
|
data = `${data}`;
|
||||||
}
|
}
|
||||||
setCaption(data || '');
|
setCaption(data || '');
|
||||||
@@ -47,10 +48,13 @@ const DatasetImageCard: React.FC<DatasetImageCardProps> = ({
|
|||||||
setIsCaptionLoaded(true);
|
setIsCaptionLoaded(true);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
if (controller.signal.aborted) return;
|
||||||
console.error('Error fetching caption:', error);
|
console.error('Error fetching caption:', error);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
isGettingCaption.current = false;
|
if (abortControllerRef.current === controller) {
|
||||||
|
abortControllerRef.current = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,6 +92,8 @@ const DatasetImageCard: React.FC<DatasetImageCardProps> = ({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setInViewport(false);
|
setInViewport(false);
|
||||||
|
// Cancel any in-flight caption fetch when scrolling away
|
||||||
|
abortControllerRef.current?.abort();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ threshold: 0.1 },
|
{ threshold: 0.1 },
|
||||||
@@ -199,11 +205,6 @@ const DatasetImageCard: React.FC<DatasetImageCardProps> = ({
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{inViewport && isVisible && !isItAudio && (
|
|
||||||
<div className="text-xs text-gray-100 bg-gray-950 mt-1 absolute bottom-0 left-0 p-1 opacity-25 hover:opacity-90 transition-opacity duration-300 w-full">
|
|
||||||
{imageUrl}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classNames('w-full p-2 bg-gray-800 text-white text-sm rounded-b-lg h-[75px]', {
|
className={classNames('w-full p-2 bg-gray-800 text-white text-sm rounded-b-lg h-[75px]', {
|
||||||
|
|||||||
Reference in new issue
Block a user