phase-8f: persistant cache locally
This commit is contained in:
committed by
saikiranvella
parent
ff1b99910b
commit
5af9ded35e
@@ -1,9 +1,16 @@
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { YahooFinanceClient } from '../clients/YahooFinanceClient';
|
||||
import { REGIME } from '../config/constants';
|
||||
import type { MarketContext, Logger, BenchmarkProviderOptions } from '../types';
|
||||
|
||||
interface CacheFile {
|
||||
data: MarketContext;
|
||||
expiresAt: number;
|
||||
}
|
||||
|
||||
export class BenchmarkProvider {
|
||||
private static readonly TTL_MS = 60 * 60 * 1000;
|
||||
private static readonly CACHE_PATH = '.benchmark-cache.json';
|
||||
|
||||
private static readonly DEFAULTS: MarketContext = {
|
||||
sp500Price: 5000,
|
||||
@@ -32,10 +39,33 @@ export class BenchmarkProvider {
|
||||
private readonly client: YahooFinanceClient,
|
||||
{ logger }: BenchmarkProviderOptions = {},
|
||||
) {
|
||||
this.cache = { data: null, expiresAt: 0 };
|
||||
this.cache = this.loadDiskCache();
|
||||
this.logger = logger ?? (console as unknown as Logger);
|
||||
}
|
||||
|
||||
private loadDiskCache(): { data: MarketContext | null; expiresAt: number } {
|
||||
try {
|
||||
if (!existsSync(BenchmarkProvider.CACHE_PATH)) return { data: null, expiresAt: 0 };
|
||||
const file = JSON.parse(readFileSync(BenchmarkProvider.CACHE_PATH, 'utf8')) as CacheFile;
|
||||
if (Date.now() < file.expiresAt) return { data: file.data, expiresAt: file.expiresAt };
|
||||
} catch {
|
||||
// corrupt or missing — ignore
|
||||
}
|
||||
return { data: null, expiresAt: 0 };
|
||||
}
|
||||
|
||||
private saveDiskCache(data: MarketContext, expiresAt: number): void {
|
||||
try {
|
||||
writeFileSync(
|
||||
BenchmarkProvider.CACHE_PATH,
|
||||
JSON.stringify({ data, expiresAt } satisfies CacheFile, null, 2),
|
||||
'utf8',
|
||||
);
|
||||
} catch {
|
||||
// non-fatal — in-memory cache still works
|
||||
}
|
||||
}
|
||||
|
||||
async getMarketContext(): Promise<MarketContext> {
|
||||
if (this.cache.data && Date.now() < this.cache.expiresAt) return this.cache.data;
|
||||
|
||||
@@ -75,7 +105,9 @@ export class BenchmarkProvider {
|
||||
},
|
||||
};
|
||||
|
||||
this.cache = { data: context, expiresAt: Date.now() + BenchmarkProvider.TTL_MS };
|
||||
const expiresAt = Date.now() + BenchmarkProvider.TTL_MS;
|
||||
this.cache = { data: context, expiresAt };
|
||||
this.saveDiskCache(context, expiresAt);
|
||||
return context;
|
||||
} catch (err) {
|
||||
this.logger.warn('Market data fetch failed, using defaults:', (err as Error).message);
|
||||
|
||||
Reference in New Issue
Block a user