Skip to content

Commit b06ac66

Browse files
committed
chore: added logging
1 parent 3823e64 commit b06ac66

File tree

3 files changed

+65
-19
lines changed

3 files changed

+65
-19
lines changed
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
11

22
import { getPublisherAverageScoreHistory, getPublisherRankingHistory, getPublishers, getRankingsByPublisher, getRankingsBySymbol } from "../services/clickhouse";
33
import { Cluster } from "../services/pyth";
4-
import { createChunkedCacheFetcher, fetchAllChunks } from '../utils/cache';
4+
import { createChunkedCacheFetcher, fetchAllChunks, timeFunction } from '../utils/cache';
55

66

77
const _getRankingsBySymbol = createChunkedCacheFetcher(async (symbol: string) => {
88
return getRankingsBySymbol(symbol);
99
}, 'getRankingsBySymbol');
1010

1111
export const getRankingsBySymbolCached = async (symbol: string) => {
12-
return fetchAllChunks<ReturnType<typeof getRankingsBySymbol>, [string]>(_getRankingsBySymbol, symbol);
12+
return timeFunction(async () => {
13+
return fetchAllChunks<ReturnType<typeof getRankingsBySymbol>, [string]>(_getRankingsBySymbol, symbol);
14+
}, 'getRankingsBySymbolCached');
1315
};
1416

1517
const _getRankingsByPublisher = createChunkedCacheFetcher(async (publisherKey: string) => {
1618
return getRankingsByPublisher(publisherKey);
1719
}, 'getRankingsByPublisher');
1820

1921
export const getRankingsByPublisherCached = async (publisherKey: string) => {
20-
return fetchAllChunks<ReturnType<typeof getRankingsByPublisher>, [string]>(_getRankingsByPublisher, publisherKey);
22+
return timeFunction(async () => {
23+
return fetchAllChunks<ReturnType<typeof getRankingsByPublisher>, [string]>(_getRankingsByPublisher, publisherKey);
24+
}, 'getRankingsByPublisherCached');
2125
};
2226

2327
const _getPublisherAverageScoreHistory = createChunkedCacheFetcher(async (cluster: Cluster, key: string) => {
2428
return getPublisherAverageScoreHistory(cluster, key);
2529
}, 'getPublisherAverageScoreHistory');
2630

2731
export const getPublisherAverageScoreHistoryCached = async (cluster: Cluster, key: string) => {
28-
return fetchAllChunks<ReturnType<typeof getPublisherAverageScoreHistory>, [Cluster, string]>(_getPublisherAverageScoreHistory, cluster, key);
32+
return timeFunction(async () => {
33+
return fetchAllChunks<ReturnType<typeof getPublisherAverageScoreHistory>, [Cluster, string]>(_getPublisherAverageScoreHistory, cluster, key);
34+
}, 'getPublisherAverageScoreHistoryCached');
2935
};
3036

3137
const _getPublisherRankingHistory = createChunkedCacheFetcher(async (cluster: Cluster, key: string) => {
3238
return getPublisherRankingHistory(cluster, key);
3339
}, 'getPublisherRankingHistory');
3440

3541
export const getPublisherRankingHistoryCached = async (cluster: Cluster, key: string) => {
36-
return fetchAllChunks<ReturnType<typeof getPublisherRankingHistory>, [Cluster, string]>(_getPublisherRankingHistory, cluster, key);
42+
return timeFunction(async () => {
43+
return fetchAllChunks<ReturnType<typeof getPublisherRankingHistory>, [Cluster, string]>(_getPublisherRankingHistory, cluster, key);
44+
}, 'getPublisherRankingHistoryCached');
3745
};
3846

3947
const _getPublishers = createChunkedCacheFetcher(async (cluster: Cluster) => {
4048
return getPublishers(cluster);
4149
}, 'getPublishers');
4250

4351
export const getPublishersCached = async (cluster: Cluster) => {
44-
return fetchAllChunks<ReturnType<typeof getPublishers>, [Cluster]>(_getPublishers, cluster);
52+
return timeFunction(async () => {
53+
return fetchAllChunks<ReturnType<typeof getPublishers>, [Cluster]>(_getPublishers, cluster);
54+
}, 'getPublishersCached');
4555
}

apps/insights/src/server/pyth.ts

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,52 @@ import type { PythHttpClientResult } from '@pythnetwork/client/lib/PythHttpClien
22
import type { z } from 'zod';
33

44
import { 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>();
1415
const CACHE_EXPIRY_MS = 24 * 60 * 60; // 1 day in seconds
1516

1617
const 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

3147
const 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

5573
const 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

6585
export 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

6991
export 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

7498
export 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(

apps/insights/src/utils/cache.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,13 @@ export async function fetchAllChunks<T, Args extends unknown[]>(
7575
firstChunkData.chunk + otherChunks.map(({ chunk }) => chunk).join("");
7676
return superjson.parse(fullString);
7777
}
78+
79+
80+
export const timeFunction = async <T>(fn: () => Promise<T>, name: string) => {
81+
const start = Date.now();
82+
const result = await fn();
83+
const end = Date.now();
84+
// eslint-disable-next-line no-console
85+
console.info(`${name} took ${(end - start).toString()}ms`);
86+
return result;
87+
}

0 commit comments

Comments
 (0)