Skip to content

Commit

Permalink
fix: cache gql and rpc call responses
Browse files Browse the repository at this point in the history
  • Loading branch information
SarjuHansaliya committed Dec 17, 2023
1 parent 224e1b3 commit 76e425b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 16 deletions.
41 changes: 31 additions & 10 deletions src/utils/calls.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Interface, Result} from '@ethersproject/abi';
import {BigNumber} from '@ethersproject/bignumber';
import {hexStripZeros, hexZeroPad} from '@ethersproject/bytes';
import {ERC20_ABI, MINICHEF_ABI, REWARDER_VIA_MULTIPLIER_ABI} from '../constants';
import {CloudflareWorkerKV, PoolInfo} from './interfaces';
import { Interface } from '@ethersproject/abi';

Check failure on line 1 in src/utils/calls.ts

View workflow job for this annotation

GitHub Actions / Lint

Replace `·Interface·` with `Interface`
import { BigNumber } from '@ethersproject/bignumber';

Check failure on line 2 in src/utils/calls.ts

View workflow job for this annotation

GitHub Actions / Lint

Replace `·BigNumber·` with `BigNumber`
import { hexStripZeros, hexZeroPad } from '@ethersproject/bytes';

Check failure on line 3 in src/utils/calls.ts

View workflow job for this annotation

GitHub Actions / Lint

Replace `·hexStripZeros,·hexZeroPad·` with `hexStripZeros,·hexZeroPad`
import { ERC20_ABI, MINICHEF_ABI, REWARDER_VIA_MULTIPLIER_ABI } from '../constants';

Check failure on line 4 in src/utils/calls.ts

View workflow job for this annotation

GitHub Actions / Lint

Replace `·ERC20_ABI,·MINICHEF_ABI,·REWARDER_VIA_MULTIPLIER_ABI·` with `ERC20_ABI,·MINICHEF_ABI,·REWARDER_VIA_MULTIPLIER_ABI`
import { CloudflareWorkerKV, PoolInfo } from './interfaces';

export function normalizeAddress(address: string): string {
return hexZeroPad(hexStripZeros(address), 20);
Expand Down Expand Up @@ -136,6 +136,14 @@ export async function getBalance(rpc: string, erc20: string, address: string): P
return BigNumber.from(await call(rpc, ERC20_ABI, erc20, 'balanceOf', [address]));
}

interface CacheEntry {
timestamp: number;
data: any;
}

const rpcCache: Record<string, CacheEntry> = {};
const CACHE_EXPIRE_TIME = 5 * 60 * 1000; // 5 minutes

export async function call(
rpc: string,
abi: any[],
Expand All @@ -144,10 +152,17 @@ export async function call(
functionData: any[] = [],
) {
const iface = new Interface(abi);
const cacheKey = `${rpc}|${toAddress}|${functionName}|${JSON.stringify(functionData)}`;
const currentTime = Date.now();

const _ = await fetch(rpc, {
// Check if the cache contains a valid entry
if (rpcCache[cacheKey] && currentTime - rpcCache[cacheKey].timestamp < CACHE_EXPIRE_TIME) {
return rpcCache[cacheKey].data;
}

const response = await fetch(rpc, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: 1,
jsonrpc: '2.0',
Expand All @@ -162,13 +177,19 @@ export async function call(
}),
});

if (_.status !== 200) {
const message = `[${_.statusText}]: Error fetching ${toAddress}.${functionName}(...)`;
if (response.status !== 200) {
const message = `[${response.statusText}]: Error fetching ${toAddress}.${functionName}(...)`;
console.error(message);
throw new Error(message);
}

const {result} = await _.json();
const { result } = await response.json();

// Cache the new data with a timestamp
rpcCache[cacheKey] = {
timestamp: currentTime,
data: result,
};

return result;
}
34 changes: 28 additions & 6 deletions src/utils/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function getTokenPriceUSD(url: string | undefined, address: string)
export async function getTokenInfo(
url: string | undefined,
address: string,
): Promise<{decimals: string; derivedETH: string}> {
): Promise<{ decimals: string; derivedETH: string }> {
const response = await request(QUERIES.TOKEN_INFO, url, {
address: address.toLowerCase(),
});
Expand All @@ -39,27 +39,49 @@ export async function getETHPrice(url: string | undefined): Promise<string> {
return response.bundle.ethPrice;
}

interface CacheEntry {
timestamp: number;
data: any;
}

const gqlCache: Record<string, CacheEntry> = {};
const CACHE_EXPIRE_TIME = 5 * 60 * 1000; // 5 minutes

export async function request(query: string, url: string | undefined, variables = {}) {
if (url === undefined) {
throw new Error(`Missing subgraph url`);
}

const _ = await fetch(url, {
const cacheKey = `${url}|${query}|${JSON.stringify(variables)}`;
const currentTime = Date.now();

// Check if the cache contains a valid entry
if (gqlCache[cacheKey] && currentTime - gqlCache[cacheKey].timestamp < CACHE_EXPIRE_TIME) {
return gqlCache[cacheKey].data;
}

const response = await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query,
variables,
}),
});

if (_.status !== 200) {
const message = `[${_.statusText}]: Error querying ${query}`;
if (response.status !== 200) {
const message = `[${response.statusText}]: Error querying ${query}`;
console.error(message);
throw new Error(message);
}

const {data} = await _.json();
const { data } = await response.json();

// Cache the new data with a timestamp
gqlCache[cacheKey] = {
timestamp: currentTime,
data,
};

return data;
}

0 comments on commit 76e425b

Please sign in to comment.