Skip to content

Commit

Permalink
adding missing file
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecot committed Jan 4, 2024
1 parent a83d0c8 commit b83f464
Showing 1 changed file with 77 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/queryCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// src/queryCache.ts

import { FastifyRequest, FastifyReply } from 'fastify';
import url from 'url';

interface CacheEntry {
isFetching: boolean;
data: any;
expiry: number;
}

class RequestCache {
cache: Record<string, CacheEntry> = {};

async getOrFetchData(request: FastifyRequest, reply: FastifyReply, handler: (request: FastifyRequest, reply: FastifyReply) => Promise<any>) {
const key = url.parse(request.url).pathname || request.url;

if (key === '') {
console.error('QueryCache: Error: Key is an empty string');
throw new Error('Key cannot be an empty string');
}

if (!this.cache[key]) {
console.log(`QueryCache: No cache entry for ${key}. Fetching data...`);
await this.tryFetchData(key, request, reply, handler);

} else if (this.cache[key].isFetching) {
console.log(`QueryCache: Data for ${key} is currently being fetched...`);

} else if (Date.now() > this.cache[key].expiry) {
console.log(`QueryCache: Cache entry for ${key} has expired. Refreshing...`);
this.tryFetchData(key, request, reply, handler);
}

return this.cache[key]?.data || {};
}

async tryFetchData(key: string, request: FastifyRequest, reply: FastifyReply, handler: (request: FastifyRequest, reply: FastifyReply) => Promise<any>, retryCount: number = 0) {
if (this.cache[key]) {
// If the key exists, only update the properties
this.cache[key].isFetching = true;
this.cache[key].expiry = Date.now() + Math.floor(Math.random() * (25 - 15 + 1) + 15) * 1000; // Random number between 15 and 25 seconds
} else {
// If the key doesn't exist, create a new entry
this.cache[key] = {
isFetching: true,
data: {},
expiry: Date.now() + Math.floor(Math.random() * (25 - 15 + 1) + 15) * 1000, // Random number between 15 and 25 seconds
};
}

try {
console.time(`QueryCache: handler execution time for ${key}`);
const data = await handler(request, reply);
console.timeEnd(`QueryCache: handler execution time for ${key}`);
this.cache[key].data = data;
this.cache[key].isFetching = false;
console.log(`QueryCache: Data fetched for ${key}`);
} catch (error) {
console.log(`QueryCache: Error fetching data for ${key} on attempt ${retryCount + 1}`);
this.cache[key].isFetching = false;
if (retryCount < 2) { // If it's not the last attempt
setTimeout(() => {
this.tryFetchData(key, request, reply, handler, retryCount + 1);
}, 1000);
}
}
}

handleRequestWithCache(handler: (request: FastifyRequest, reply: FastifyReply) => Promise<any>): (request: FastifyRequest, reply: FastifyReply) => Promise<any> {
return async (request: FastifyRequest, reply: FastifyReply) => {
return await this.getOrFetchData(request, reply, handler);
};
}
}

export default RequestCache;

0 comments on commit b83f464

Please sign in to comment.