mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 00:32:03 +00:00
use per-content promise map for concurrent decryption
This commit is contained in:
parent
c54785353e
commit
f0f5b54768
@ -4,7 +4,8 @@ import axios from 'axios';
|
|||||||
export const useDecryptContent = () => {
|
export const useDecryptContent = () => {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const inProgressRef = useRef(false);
|
// Map of in-progress decryption promises, keyed by content hash
|
||||||
|
const inProgressMap = useRef(new Map());
|
||||||
const cachedResults = useRef({});
|
const cachedResults = useRef({});
|
||||||
|
|
||||||
const decryptContent = async (encryptedContent) => {
|
const decryptContent = async (encryptedContent) => {
|
||||||
@ -13,49 +14,63 @@ export const useDecryptContent = () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent multiple simultaneous calls
|
// Use first 20 chars as our cache/lock key
|
||||||
if (inProgressRef.current) {
|
const cacheKey = encryptedContent.substring(0, 20);
|
||||||
// Wait for a small delay to prevent tight loop
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
|
||||||
|
|
||||||
// Return a cached result if we have one
|
|
||||||
const firstChars = encryptedContent.substring(0, 20);
|
|
||||||
if (cachedResults.current[firstChars]) {
|
|
||||||
return cachedResults.current[firstChars];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we've already decrypted this content
|
// Check if we've already decrypted this content
|
||||||
const firstChars = encryptedContent.substring(0, 20);
|
if (cachedResults.current[cacheKey]) {
|
||||||
if (cachedResults.current[firstChars]) {
|
return cachedResults.current[cacheKey];
|
||||||
return cachedResults.current[firstChars];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// Check if this specific content is already being decrypted
|
||||||
inProgressRef.current = true;
|
if (inProgressMap.current.has(cacheKey)) {
|
||||||
setIsLoading(true);
|
// Return the existing promise for this content
|
||||||
setError(null);
|
try {
|
||||||
|
return await inProgressMap.current.get(cacheKey);
|
||||||
const response = await axios.post('/api/decrypt', { encryptedContent });
|
} catch (error) {
|
||||||
|
// If the existing promise rejects, we'll try again below
|
||||||
if (response.status !== 200) {
|
console.warn('Previous decryption attempt failed, retrying');
|
||||||
throw new Error(`Failed to decrypt: ${response.statusText}`);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const decryptedContent = response.data.decryptedContent;
|
|
||||||
|
// Create a new decryption promise for this content
|
||||||
// Cache the result
|
const decryptPromise = (async () => {
|
||||||
cachedResults.current[firstChars] = decryptedContent;
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
return decryptedContent;
|
setError(null);
|
||||||
|
|
||||||
|
const response = await axios.post('/api/decrypt', { encryptedContent });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(`Failed to decrypt: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const decryptedContent = response.data.decryptedContent;
|
||||||
|
|
||||||
|
// Cache the successful result
|
||||||
|
cachedResults.current[cacheKey] = decryptedContent;
|
||||||
|
|
||||||
|
return decryptedContent;
|
||||||
|
} catch (error) {
|
||||||
|
setError(error.message || 'Decryption failed');
|
||||||
|
// Re-throw to signal failure to awaiter
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
// Remove this promise from the in-progress map
|
||||||
|
inProgressMap.current.delete(cacheKey);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Store the promise in our map
|
||||||
|
inProgressMap.current.set(cacheKey, decryptPromise);
|
||||||
|
|
||||||
|
// Return the promise
|
||||||
|
try {
|
||||||
|
return await decryptPromise;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError(error.message || 'Decryption failed');
|
// We've already set the error state in the promise
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
inProgressRef.current = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user