@@ -2,34 +2,52 @@ import type { PythHttpClientResult } from '@pythnetwork/client/lib/PythHttpClien
22import type { z } from 'zod' ;
33
44import { Cluster , clients , priceFeedsSchema } from "../services/pyth" ;
5- import { createChunkedCacheFetcher , fetchAllChunks } from '../utils/cache' ;
5+ import { createChunkedCacheFetcher , fetchAllChunks , timeFunction } from '../utils/cache' ;
66
77
8- type CachedData = {
9- data : PythHttpClientResult ;
10- timestamp : number ;
8+ type CacheEntry = {
9+ data ?: PythHttpClientResult ;
10+ timestamp ?: number ;
11+ promise ?: Promise < PythHttpClientResult > ;
1112} ;
1213
13- const dataCache = new Map < Cluster , CachedData > ( ) ;
14+ const dataCache = new Map < Cluster , CacheEntry > ( ) ;
1415const CACHE_EXPIRY_MS = 24 * 60 * 60 ; // 1 day in seconds
1516
1617const getDataCached = async ( cluster : Cluster ) => {
1718 const now = Date . now ( ) ;
1819 const cached = dataCache . get ( cluster ) ;
1920
2021 // Check if cache exists and is not expired
21- if ( cached && ( now - cached . timestamp ) < CACHE_EXPIRY_MS * 1000 ) {
22+ if ( cached ?. data && cached . timestamp && ( now - cached . timestamp ) < CACHE_EXPIRY_MS * 1000 ) {
2223 return cached . data ;
2324 }
2425
25- // Fetch fresh data
26- const data = await clients [ cluster ] . getData ( ) ;
27- dataCache . set ( cluster , { data, timestamp : now } ) ;
28- return data ;
26+ // Check if there's already a pending request
27+ if ( cached ?. promise ) {
28+ return cached . promise ;
29+ }
30+
31+ // eslint-disable-next-line no-console
32+ console . log ( 'fetching fresh FULL data' ) ;
33+
34+ // Create a new promise for the request
35+ const promise = clients [ cluster ] . getData ( ) . then ( ( data ) => {
36+ // Store the result in cache
37+ dataCache . set ( cluster , { data, timestamp : now } ) ;
38+ return data ;
39+ } ) ;
40+
41+ // Store the promise in cache to prevent duplicate requests
42+ dataCache . set ( cluster , { promise } ) ;
43+
44+ return promise ;
2945} ;
3046
3147const fetchFeeds = createChunkedCacheFetcher ( async ( cluster : Cluster ) => {
3248 const unfilteredData = await getDataCached ( cluster ) ;
49+ // eslint-disable-next-line no-console
50+ console . log ( 'fetchFeeds called' ) ;
3351 const filteredData = unfilteredData . symbols
3452 . filter (
3553 ( symbol ) =>
@@ -54,6 +72,8 @@ const fetchFeeds = createChunkedCacheFetcher(async (cluster: Cluster) => {
5472
5573const fetchPublishers = createChunkedCacheFetcher ( async ( cluster : Cluster ) => {
5674 const data = await getDataCached ( cluster ) ;
75+ // eslint-disable-next-line no-console
76+ console . log ( 'fetchPublishers called' ) ;
5777 const result : Record < string , string [ ] > = { } ;
5878 for ( const key of data . productPrice . keys ( ) ) {
5979 const price = data . productPrice . get ( key ) ;
@@ -63,19 +83,25 @@ const fetchPublishers = createChunkedCacheFetcher(async (cluster: Cluster) => {
6383} , 'fetchPublishers' ) ;
6484
6585export const getFeedsCached = async ( cluster : Cluster ) => {
66- return fetchAllChunks < z . infer < typeof priceFeedsSchema > , [ Cluster ] > ( fetchFeeds , cluster )
86+ return timeFunction ( async ( ) => {
87+ return fetchAllChunks < z . infer < typeof priceFeedsSchema > , [ Cluster ] > ( fetchFeeds , cluster ) ;
88+ } , 'getFeedsCached' ) ;
6789} ;
6890
6991export const getPublishersForFeedCached = async ( cluster : Cluster , symbol : string ) => {
70- const data = await fetchAllChunks < Record < string , string [ ] > , [ Cluster ] > ( fetchPublishers , cluster ) ;
92+ const data = await timeFunction ( async ( ) => {
93+ return fetchAllChunks < Record < string , string [ ] > , [ Cluster ] > ( fetchPublishers , cluster ) ;
94+ } , 'getPublishersForFeedCached' ) ;
7195 return data [ symbol ]
7296} ;
7397
7498export const getFeedsForPublisherCached = async (
7599 cluster : Cluster ,
76100 publisher : string
77101) => {
78- const data = await getFeedsCached ( cluster ) ;
102+ const data = await timeFunction ( async ( ) => {
103+ return getFeedsCached ( cluster ) ;
104+ } , 'getFeedsForPublisherCached' ) ;
79105 return priceFeedsSchema . parse (
80106 data . filter ( ( { price } ) =>
81107 price . priceComponents . some (
0 commit comments