fix(dnscache): use entry specific hits and misses not global

This commit is contained in:
fallenbagel
2025-02-23 05:14:24 +08:00
committed by gauthier-th
parent 7ddca119a8
commit 00728dafdf
6 changed files with 51 additions and 12 deletions

View File

@@ -3023,6 +3023,12 @@ paths:
networkErrors:
type: number
example: 0
hits:
type: number
example: 1
misses:
type: number
example: 1
apiCaches:
type: array
items:

View File

@@ -73,6 +73,8 @@ export interface DNSRecord {
age: number;
ttl: number;
networkErrors: number;
hits: number;
misses: number;
}
export interface DNSStats {

View File

@@ -758,6 +758,8 @@ settingsRoutes.get('/cache', async (_req, res) => {
const stats = dnsCache.getStats();
const entries = dnsCache.getCacheEntries();
console.log(entries);
console.log(stats);
return res.status(200).json({
apiCaches,

View File

@@ -41,6 +41,8 @@ interface DnsCache {
timestamp: number;
ttl: number;
networkErrors?: number;
hits: number;
misses: number;
}
interface CacheStats {
@@ -172,6 +174,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: 60000,
networkErrors: 0,
hits: 0,
misses: 0,
};
this.updateCache(hostname, cacheEntry).catch(() => {
@@ -264,6 +268,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: 0,
networkErrors: 0,
hits: 0,
misses: 0,
};
}
@@ -300,12 +306,14 @@ class DnsCacheManager {
};
}
cached.hits++;
this.stats.hits++;
return cached;
}
// Soft expiration. Will use stale entry while refreshing
if (age < this.hardTtlMs) {
cached.hits++;
this.stats.hits++;
// Background refresh
@@ -323,6 +331,7 @@ class DnsCacheManager {
);
const family = activeAddress.includes(':') ? 6 : 4;
const existing = this.cache.get(hostname);
this.cache.set(hostname, {
addresses: result.addresses,
activeAddress,
@@ -330,6 +339,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: result.ttl,
networkErrors: 0,
hits: existing?.hits ?? 0,
misses: (existing?.misses ?? 0) + 1,
});
})
.catch((error) => {
@@ -342,6 +353,7 @@ class DnsCacheManager {
}
// Hard expiration to remove stale entry
cached.misses++;
this.cache.delete(hostname);
}
@@ -361,6 +373,8 @@ class DnsCacheManager {
);
const family = activeAddress.includes(':') ? 6 : 4;
const existingMisses = this.cache.get(hostname)?.misses ?? 0;
const dnsCache: DnsCache = {
addresses: result.addresses,
activeAddress,
@@ -368,6 +382,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: result.ttl,
networkErrors: 0,
hits: 0,
misses: existingMisses + 1,
};
this.cache.set(hostname, dnsCache);
@@ -479,6 +495,8 @@ class DnsCacheManager {
timestamp: entry.timestamp,
ttl: entry.ttl,
networkErrors: 0,
hits: entry.hits,
misses: entry.misses,
};
}
return entry;
@@ -568,6 +586,8 @@ class DnsCacheManager {
timestamp: entry.timestamp || Date.now(),
ttl: entry.ttl || 60000,
networkErrors: entry.networkErrors || 0,
hits: entry.hits || 0,
misses: entry.misses || 0,
};
if (
@@ -603,6 +623,8 @@ class DnsCacheManager {
timestamp: validatedEntry.timestamp,
ttl: validatedEntry.ttl,
networkErrors: 0,
hits: 0,
misses: 0,
};
this.cache.set(hostname, mergedEntry);
@@ -726,6 +748,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: 60000,
networkErrors: 0,
hits: 0,
misses: 0,
});
});
});
@@ -774,6 +798,8 @@ class DnsCacheManager {
timestamp: Date.now(),
ttl: 30000,
networkErrors: 0,
hits: 0,
misses: 0,
};
}
@@ -853,6 +879,8 @@ class DnsCacheManager {
age: number;
ttl: number;
networkErrors?: number;
hits: number;
misses: number;
}
> = {};
@@ -870,6 +898,8 @@ class DnsCacheManager {
age,
ttl,
networkErrors: data.networkErrors,
hits: data.hits,
misses: data.misses,
};
}

View File

@@ -58,7 +58,7 @@ const messages: { [messageName: string]: MessageDescriptor } = defineMessages(
dnsCache: 'DNS Cache',
dnsCacheDescription:
'Jellyseerr caches DNS lookups to optimize performance and avoid making unnecessary API calls.',
dnsCacheFlushed: '{hostname} dns cache flushed.',
dnscacheflushed: '{hostname} dns cache flushed.',
dnscachename: 'Hostname',
dnscacheactiveaddress: 'Active Address',
dnscachehits: 'Hits',
@@ -259,10 +259,13 @@ const SettingsJobs = () => {
method: 'POST',
});
if (!res.ok) throw new Error();
addToast(intl.formatMessage(messages.dnscacheflushed, { hostname }), {
appearance: 'success',
autoDismiss: true,
});
addToast(
intl.formatMessage(messages.dnscacheflushed, { hostname: hostname }),
{
appearance: 'success',
autoDismiss: true,
}
);
cacheRevalidate();
};
@@ -627,12 +630,8 @@ const SettingsJobs = () => {
<tr key={`cache-list-${hostname}`}>
<Table.TD>{hostname}</Table.TD>
<Table.TD>{data.activeAddress}</Table.TD>
<Table.TD>
{intl.formatNumber(cacheData?.dnsCache.stats.hits ?? 0)}
</Table.TD>
<Table.TD>
{intl.formatNumber(cacheData?.dnsCache.stats.misses ?? 0)}
</Table.TD>
<Table.TD>{intl.formatNumber(data.hits)}</Table.TD>
<Table.TD>{intl.formatNumber(data.misses)}</Table.TD>
<Table.TD>{formatAge(data.age)}</Table.TD>
<Table.TD>{intl.formatNumber(data.networkErrors)}</Table.TD>
<Table.TD alignText="right">

View File

@@ -875,9 +875,9 @@
"components.Settings.SettingsJobsCache.command": "Command",
"components.Settings.SettingsJobsCache.dnsCache": "DNS Cache",
"components.Settings.SettingsJobsCache.dnsCacheDescription": "Jellyseerr caches DNS lookups to optimize performance and avoid making unnecessary API calls.",
"components.Settings.SettingsJobsCache.dnsCacheFlushed": "{hostname} dns cache flushed.",
"components.Settings.SettingsJobsCache.dnscacheactiveaddress": "Active Address",
"components.Settings.SettingsJobsCache.dnscacheage": "Age",
"components.Settings.SettingsJobsCache.dnscacheflushed": "{hostname} dns cache flushed.",
"components.Settings.SettingsJobsCache.dnscachehits": "Hits",
"components.Settings.SettingsJobsCache.dnscachemisses": "Misses",
"components.Settings.SettingsJobsCache.dnscachename": "Hostname",