Skip to content

Commit

Permalink
Batch cached execs fetches and deletions (#966)
Browse files Browse the repository at this point in the history
* Batch cached execs fetches and deletions

* Dynamically import lottie
  • Loading branch information
hernandoagf authored Dec 17, 2024
1 parent c6ce69e commit 5574da5
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 41 deletions.
76 changes: 51 additions & 25 deletions modules/app/components/TxIndicators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,78 @@ SPDX-License-Identifier: AGPL-3.0-or-later

import { Box, ThemeUIStyleObject } from 'theme-ui';
import { useEffect } from 'react';
import lottie from 'lottie-web';

import txFailedAnimation from 'lib/animation/txFailed.json';
import txSuccessAnimation from 'lib/animation/txSuccess.json';
import txPendingAnimation from 'lib/animation/txPending.json';

const Failed = ({ done, ...props }: { done?: () => void; sx?: ThemeUIStyleObject }): React.ReactElement => {
useEffect(() => {
const animation = lottie.loadAnimation({
container: document.getElementById('tx-failed-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: txFailedAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));
const loadLottie = async () => {
const lottie = await import('lottie-web');
const animation = lottie.default.loadAnimation({
container: document.getElementById('tx-failed-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: txFailedAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));

return () => {
animation.destroy();
};
};

loadLottie();
}, []);

return <Box sx={{ width: '100%' }} id="tx-failed-animation-container" {...props} />;
};

const Success = ({ done, ...props }: { done?: () => void; sx?: ThemeUIStyleObject }): React.ReactElement => {
useEffect(() => {
const animation = lottie.loadAnimation({
container: document.getElementById('tx-success-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: txSuccessAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));
const loadLottie = async () => {
const lottie = await import('lottie-web');
const animation = lottie.default.loadAnimation({
container: document.getElementById('tx-success-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: txSuccessAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));

return () => {
animation.destroy();
};
};

loadLottie();
}, []);

return <Box sx={{ width: '100%' }} id="tx-success-animation-container" {...props} />;
};

const Pending = ({ done, ...props }: { done?: () => void; sx?: ThemeUIStyleObject }): React.ReactElement => {
useEffect(() => {
const animation = lottie.loadAnimation({
container: document.getElementById('tx-pending-animation-container') as HTMLElement,
loop: true,
autoplay: true,
animationData: txPendingAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));
const loadLottie = async () => {
const lottie = await import('lottie-web');
const animation = lottie.default.loadAnimation({
container: document.getElementById('tx-pending-animation-container') as HTMLElement,
loop: true,
autoplay: true,
animationData: txPendingAnimation
});

done && animation.addEventListener('complete', () => setTimeout(done, 200));

return () => {
animation.destroy();
};
};

loadLottie();
}, []);

return <Box sx={{ width: '100%' }} id="tx-pending-animation-container" {...props} />;
Expand Down
33 changes: 26 additions & 7 deletions modules/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,30 @@ export const cacheDel = (name: string, network: SupportedNetworks, expiryMs?: nu
if (redisCacheEnabled()) {
// if clearing proposals, we need to find all of them first
if (name === 'proposals') {
redis?.keys('*proposals*').then(keys => {
keys.forEach(key => {
logger.debug('cacheDel key: ', key);
redis?.del(key);
});
const deleteProposalKeys = async () => {
let cursor = '0';
do {
const pipeline = (redis as Redis).pipeline();
const [nextCursor, keys] = await (redis as Redis).scan(
cursor,
'MATCH',
'*proposals*',
'COUNT',
'100'
);

if (keys.length > 0) {
logger.debug('cacheDel pattern: *proposals* ', cursor, keys.length);
pipeline.del(...keys);
}

await pipeline.exec();
cursor = nextCursor;
} while (cursor !== '0');
};

deleteProposalKeys().catch(error => {
logger.error('Error deleting proposal keys:', error);
});
} else {
// otherwise just delete the file based on path
Expand Down Expand Up @@ -90,8 +109,8 @@ export const getCacheInfo = async (name: string, network: SupportedNetworks): Pr
// if fetching proposals cache info, there are likely multiple keys cached due to different query params
// we'll return the ttl for first proposals key we find
if (name === executiveProposalsCacheKey) {
const keys = await redis?.keys('*proposals*');
if (keys && keys.length > 0) {
const [, keys] = await (redis as Redis).scan('0', 'MATCH', '*proposals*', 'COUNT', '1');
if (keys.length > 0) {
const ttl = await redis?.ttl(keys[0]);
return ttl;
}
Expand Down
26 changes: 17 additions & 9 deletions modules/polling/components/MobileVoteSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Text, Button, Box, Flex } from 'theme-ui';
import invariant from 'tiny-invariant';
import range from 'lodash/range';
import isNil from 'lodash/isNil';
import lottie from 'lottie-web';
import { Poll } from 'modules/polling/types';
import Stack from 'modules/app/components/layout/layouts/Stack';
import { useRouter } from 'next/router';
Expand Down Expand Up @@ -198,14 +197,23 @@ export default function MobileVoteSheet({

const AddingView = ({ done }: { done: () => void }) => {
useEffect(() => {
const animation = lottie.loadAnimation({
container: document.getElementById('ballot-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: ballotAnimation
});

animation.addEventListener('complete', () => setTimeout(done, 200));
const loadLottie = async () => {
const lottie = await import('lottie-web');
const animation = lottie.default.loadAnimation({
container: document.getElementById('ballot-animation-container') as HTMLElement,
loop: false,
autoplay: true,
animationData: ballotAnimation
});

animation.addEventListener('complete', () => setTimeout(done, 200));

return () => {
animation.destroy();
};
};

loadLottie();
}, []);

return (
Expand Down

0 comments on commit 5574da5

Please sign in to comment.