clean up decryption and retry timers on unmount to prevent memory leaks

This commit is contained in:
austinkelsay 2025-05-12 09:37:32 -05:00
parent bac65c0dd3
commit 5a79523ba0
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE

View File

@ -8,6 +8,8 @@ const useCourseDecryption = (session, paidCourse, course, lessons, setLessons, r
const processingRef = useRef(false); const processingRef = useRef(false);
const lastLessonIdRef = useRef(null); const lastLessonIdRef = useRef(null);
const retryCountRef = useRef({}); const retryCountRef = useRef({});
const retryTimeoutRef = useRef(null);
const decryptTimeoutRef = useRef(null);
const MAX_RETRIES = 3; const MAX_RETRIES = 3;
// Get the current active lesson using the activeIndex prop instead of router.query // Get the current active lesson using the activeIndex prop instead of router.query
@ -70,12 +72,12 @@ const useCourseDecryption = (session, paidCourse, course, lessons, setLessons, r
let timeoutId; let timeoutId;
const timeoutPromise = new Promise((_, reject) => { const timeoutPromise = new Promise((_, reject) => {
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
// Cancel the in-flight request when timeout occurs
if (decryptionPromise.cancel) { if (decryptionPromise.cancel) {
decryptionPromise.cancel(); decryptionPromise.cancel();
} }
reject(new Error('Decryption timeout')); reject(new Error('Decryption timeout'));
}, 10000); }, 10000);
decryptTimeoutRef.current = timeoutId;
}); });
// Use a separate try-catch for the race // Use a separate try-catch for the race
@ -89,9 +91,10 @@ const useCourseDecryption = (session, paidCourse, course, lessons, setLessons, r
// Clear the timeout if decryption wins // Clear the timeout if decryption wins
clearTimeout(timeoutId); clearTimeout(timeoutId);
decryptTimeoutRef.current = null;
} catch (error) { } catch (error) {
// If timeout or network error, schedule a retry // If timeout or network error, schedule a retry
setTimeout(() => { retryTimeoutRef.current = setTimeout(() => {
processingRef.current = false; processingRef.current = false;
decryptCurrentLesson(); decryptCurrentLesson();
}, 5000); }, 5000);
@ -138,6 +141,19 @@ const useCourseDecryption = (session, paidCourse, course, lessons, setLessons, r
} }
}, [currentLessonId, hasAccess, paidCourse, decryptedLessonIds, decryptCurrentLesson, activeIndex]); }, [currentLessonId, hasAccess, paidCourse, decryptedLessonIds, decryptCurrentLesson, activeIndex]);
useEffect(() => {
return () => {
if (decryptTimeoutRef.current) {
clearTimeout(decryptTimeoutRef.current);
decryptTimeoutRef.current = null;
}
if (retryTimeoutRef.current) {
clearTimeout(retryTimeoutRef.current);
retryTimeoutRef.current = null;
}
};
}, []);
return { return {
decryptionPerformed: isCurrentLessonDecrypted, decryptionPerformed: isCurrentLessonDecrypted,
loading, loading,