Compare commits

...
Author SHA1 Message Date
ajnart b650bffaa8 fix(request-handler): restore cacheTtlMs values lost in v1.69.0 refactor
The v1.69.0 caching refactor (f19033e0d) replaced the old Redis-backed
cached request handler with a simpler in-memory handler but dropped
all per-handler cacheDuration values, defaulting everything to 10s.
This caused widgets that previously had short cache durations (e.g.
health-monitoring at 5s, dns-hole at 5s) to refresh much less
frequently since the client polls every 30s.

Restores cacheTtlMs for all affected request handlers to match their
pre-v1.69.0 values. Also adds cacheTtlMs support to
createWidgetRequestHandler which was missing it.

Beszel handlers are intentionally left untouched as they have their
own cache handling.

Fixes #6268
2026-07-15 10:53:36 +02:00
33 changed files with 46 additions and 0 deletions

No files matched your search

@@ -12,6 +12,7 @@ export const anchorNotesListRequestHandler = createIntegrationRequestHandler<
const instance = await createIntegrationAsync(integration); const instance = await createIntegrationAsync(integration);
return instance.listNotesAsync(input); return instance.listNotesAsync(input);
}, },
cacheTtlMs: 15_000,
}); });
export const anchorNoteRequestHandler = createIntegrationRequestHandler<AnchorNote, "anchor", { noteId: string }>({ export const anchorNoteRequestHandler = createIntegrationRequestHandler<AnchorNote, "anchor", { noteId: string }>({
@@ -19,4 +20,5 @@ export const anchorNoteRequestHandler = createIntegrationRequestHandler<AnchorNo
const instance = await createIntegrationAsync(integration); const instance = await createIntegrationAsync(integration);
return instance.getNoteAsync(input.noteId); return instance.getNoteAsync(input.noteId);
}, },
cacheTtlMs: 15_000,
}); });
@@ -13,4 +13,5 @@ export const archiveTeamWarriorRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getStatusAsync(); return await integrationInstance.getStatusAsync();
}, },
cacheTtlMs: 300_000,
}); });
@@ -12,4 +12,5 @@ export const audiobookshelfRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getDashboardDataAsync(); return await integrationInstance.getDashboardDataAsync();
}, },
cacheTtlMs: 600_000,
}); });
+1
View File
@@ -23,4 +23,5 @@ export const calendarMonthRequestHandler = createIntegrationRequestHandler<
input.showUnmonitored, input.showUnmonitored,
); );
}, },
cacheTtlMs: 60_000,
}); });
+1
View File
@@ -12,4 +12,5 @@ export const coolifyRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getInstanceInfoAsync(); return await integrationInstance.getInstanceInfoAsync();
}, },
cacheTtlMs: 30_000,
}); });
+1
View File
@@ -13,4 +13,5 @@ export const dnsHoleRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getSummaryAsync(); return await integrationInstance.getSummaryAsync();
}, },
cacheTtlMs: 5_000,
}); });
+1
View File
@@ -177,6 +177,7 @@ export const dockerContainersRequestHandler = createWidgetRequestHandler({
} }
return await getContainersWithStatsAsync(); return await getContainersWithStatsAsync();
}, },
cacheTtlMs: 20_000,
}); });
const extractImage = (container: ContainerInfo) => extractContainerImageName(container.Image); const extractImage = (container: ContainerInfo) => extractContainerImageName(container.Image);
@@ -13,4 +13,5 @@ export const downloadClientRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getClientJobsAndStatusAsync(input); return await integrationInstance.getClientJobsAndStatusAsync(input);
}, },
cacheTtlMs: 5_000,
}); });
@@ -69,4 +69,5 @@ export const duckDuckGoBangsRequestHandler = createRequestHandler({
return normalized; return normalized;
}, },
cacheTtlMs: 86_400_000,
}); });
+4
View File
@@ -18,6 +18,7 @@ export const firewallCpuRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return integrationInstance.getFirewallCpuAsync(); return integrationInstance.getFirewallCpuAsync();
}, },
cacheTtlMs: 5_000,
}); });
export const firewallMemoryRequestHandler = createIntegrationRequestHandler< export const firewallMemoryRequestHandler = createIntegrationRequestHandler<
@@ -29,6 +30,7 @@ export const firewallMemoryRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getFirewallMemoryAsync(); return await integrationInstance.getFirewallMemoryAsync();
}, },
cacheTtlMs: 15_000,
}); });
export const firewallInterfacesRequestHandler = createIntegrationRequestHandler< export const firewallInterfacesRequestHandler = createIntegrationRequestHandler<
@@ -40,6 +42,7 @@ export const firewallInterfacesRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getFirewallInterfacesAsync(); return await integrationInstance.getFirewallInterfacesAsync();
}, },
cacheTtlMs: 30_000,
}); });
export const firewallVersionRequestHandler = createIntegrationRequestHandler< export const firewallVersionRequestHandler = createIntegrationRequestHandler<
@@ -51,4 +54,5 @@ export const firewallVersionRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getFirewallVersionAsync(); return await integrationInstance.getFirewallVersionAsync();
}, },
cacheTtlMs: 3_600_000,
}); });
@@ -13,6 +13,7 @@ export const systemInfoRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getSystemInfoAsync(); return await integrationInstance.getSystemInfoAsync();
}, },
cacheTtlMs: 5_000,
}); });
export const clusterInfoRequestHandler = createIntegrationRequestHandler< export const clusterInfoRequestHandler = createIntegrationRequestHandler<
@@ -24,4 +25,5 @@ export const clusterInfoRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getClusterInfoAsync(); return await integrationInstance.getClusterInfoAsync();
}, },
cacheTtlMs: 5_000,
}); });
+3
View File
@@ -13,6 +13,7 @@ export const immichStatsRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getServerStatsAsync(); return await integrationInstance.getServerStatsAsync();
}, },
cacheTtlMs: 900_000,
}); });
export const immichAlbumsRequestHandler = createIntegrationRequestHandler< export const immichAlbumsRequestHandler = createIntegrationRequestHandler<
@@ -28,6 +29,7 @@ export const immichAlbumsRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getAlbumsAsync(); return await integrationInstance.getAlbumsAsync();
}, },
cacheTtlMs: 900_000,
}); });
export const immichAlbumRequestHandler = createIntegrationRequestHandler< export const immichAlbumRequestHandler = createIntegrationRequestHandler<
@@ -39,4 +41,5 @@ export const immichAlbumRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getAlbumAsync(input.albumId); return await integrationInstance.getAlbumAsync(input.albumId);
}, },
cacheTtlMs: 900_000,
}); });
@@ -13,4 +13,5 @@ export const indexerManagerRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getIndexersAsync(); return await integrationInstance.getIndexersAsync();
}, },
cacheTtlMs: 300_000,
}); });
@@ -2,6 +2,7 @@ import { createRequestHandler } from "./request-handler";
interface Options<TData, TInput extends Record<string, unknown>> { interface Options<TData, TInput extends Record<string, unknown>> {
requestAsync: (input: TInput) => Promise<TData>; requestAsync: (input: TInput) => Promise<TData>;
cacheTtlMs?: number;
} }
export const createWidgetRequestHandler = <TData, TInput extends Record<string, unknown>>( export const createWidgetRequestHandler = <TData, TInput extends Record<string, unknown>>(
@@ -10,5 +11,6 @@ export const createWidgetRequestHandler = <TData, TInput extends Record<string,
handler: (widgetOptions: TInput) => handler: (widgetOptions: TInput) =>
createRequestHandler<TData, TInput>({ createRequestHandler<TData, TInput>({
requestAsync: options.requestAsync, requestAsync: options.requestAsync,
cacheTtlMs: options.cacheTtlMs,
}).handler(widgetOptions), }).handler(widgetOptions),
}); });
@@ -13,4 +13,5 @@ export const mediaReleaseRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getMediaReleasesAsync(); return await integrationInstance.getMediaReleasesAsync();
}, },
cacheTtlMs: 300_000,
}); });
@@ -16,4 +16,5 @@ export const mediaRequestStatsRequestHandler = createIntegrationRequestHandler<
users: await integrationInstance.getUsersAsync(), users: await integrationInstance.getUsersAsync(),
}; };
}, },
cacheTtlMs: 60_000,
}); });
@@ -15,4 +15,5 @@ export const mediaServerRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getCurrentSessionsAsync({ showOnlyPlaying: input.showOnlyPlaying }); return await integrationInstance.getCurrentSessionsAsync({ showOnlyPlaying: input.showOnlyPlaying });
}, },
cacheTtlMs: 5_000,
}); });
@@ -17,6 +17,7 @@ export const mediaTranscodingRequestHandler = createIntegrationRequestHandler<
statistics: await integrationInstance.getStatisticsAsync(), statistics: await integrationInstance.getStatisticsAsync(),
}; };
}, },
cacheTtlMs: 300_000,
}); });
export interface MediaTranscoding { export interface MediaTranscoding {
@@ -14,6 +14,7 @@ export const minecraftServerStatusRequestHandler = createWidgetRequestHandler({
); );
return responseSchema.parse(await response.json()); return responseSchema.parse(await response.json());
}, },
cacheTtlMs: 300_000,
}); });
const responseSchema = z const responseSchema = z
@@ -12,4 +12,5 @@ export const navidromeRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getDashboardDataAsync(); return await integrationInstance.getDashboardDataAsync();
}, },
cacheTtlMs: 600_000,
}); });
@@ -13,4 +13,5 @@ export const networkControllerRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getNetworkSummaryAsync(); return await integrationInstance.getNetworkSummaryAsync();
}, },
cacheTtlMs: 300_000,
}); });
@@ -13,4 +13,5 @@ export const notificationsRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getNotificationsAsync(); return await integrationInstance.getNotificationsAsync();
}, },
cacheTtlMs: 300_000,
}); });
@@ -12,4 +12,5 @@ export const paperlessNgxStatsRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getStatsAsync(); return await integrationInstance.getStatsAsync();
}, },
cacheTtlMs: 900_000,
}); });
@@ -28,6 +28,7 @@ export const rssFeedsRequestHandler = createWidgetRequestHandler({
entries: result.entries?.map((entry) => ({ ...entry, feedUrl: input.url })).slice(0, input.count) ?? [], entries: result.entries?.map((entry) => ({ ...entry, feedUrl: input.url })).slice(0, input.count) ?? [],
}; };
}, },
cacheTtlMs: 300_000,
}); });
const attemptGetImageFromEntry = (feedUrl: string, entry: object) => { const attemptGetImageFromEntry = (feedUrl: string, entry: object) => {
@@ -18,4 +18,5 @@ export const smartHomeEntityStateRequestHandler = createIntegrationRequestHandle
return result.data.state; return result.data.state;
}, },
cacheTtlMs: 60_000,
}); });
@@ -12,4 +12,5 @@ export const speedtestTrackerRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getDashboardDataAsync(); return await integrationInstance.getDashboardDataAsync();
}, },
cacheTtlMs: 600_000,
}); });
@@ -39,6 +39,7 @@ export const fetchStockPriceHandler = createWidgetRequestHandler({
shortName: firstResult.meta.shortName, shortName: firstResult.meta.shortName,
}; };
}, },
cacheTtlMs: 300_000,
}); });
const dataSchema = z const dataSchema = z
+1
View File
@@ -12,4 +12,5 @@ export const tracearrRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getDashboardDataAsync(); return await integrationInstance.getDashboardDataAsync();
}, },
cacheTtlMs: 5_000,
}); });
+6
View File
@@ -12,6 +12,7 @@ export const umamiRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getVisitorStatsAsync(input.websiteId, input.timeFrame, input.eventName); return await integrationInstance.getVisitorStatsAsync(input.websiteId, input.timeFrame, input.eventName);
}, },
cacheTtlMs: 300_000,
}); });
export const umamiEventNamesRequestHandler = createIntegrationRequestHandler<string[], "umami", { websiteId: string }>({ export const umamiEventNamesRequestHandler = createIntegrationRequestHandler<string[], "umami", { websiteId: string }>({
@@ -19,6 +20,7 @@ export const umamiEventNamesRequestHandler = createIntegrationRequestHandler<str
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getEventNamesAsync(input.websiteId); return await integrationInstance.getEventNamesAsync(input.websiteId);
}, },
cacheTtlMs: 300_000,
}); });
export const umamiTopPagesRequestHandler = createIntegrationRequestHandler< export const umamiTopPagesRequestHandler = createIntegrationRequestHandler<
@@ -30,6 +32,7 @@ export const umamiTopPagesRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getTopPagesAsync(input.websiteId, input.timeFrame, input.limit); return await integrationInstance.getTopPagesAsync(input.websiteId, input.timeFrame, input.limit);
}, },
cacheTtlMs: 300_000,
}); });
export const umamiTopReferrersRequestHandler = createIntegrationRequestHandler< export const umamiTopReferrersRequestHandler = createIntegrationRequestHandler<
@@ -41,6 +44,7 @@ export const umamiTopReferrersRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getTopReferrersAsync(input.websiteId, input.timeFrame, input.limit); return await integrationInstance.getTopReferrersAsync(input.websiteId, input.timeFrame, input.limit);
}, },
cacheTtlMs: 300_000,
}); });
export const umamiMultiEventRequestHandler = createIntegrationRequestHandler< export const umamiMultiEventRequestHandler = createIntegrationRequestHandler<
@@ -52,6 +56,7 @@ export const umamiMultiEventRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getMultiEventTimeSeriesAsync(input.websiteId, input.timeFrame, input.eventNames); return await integrationInstance.getMultiEventTimeSeriesAsync(input.websiteId, input.timeFrame, input.eventNames);
}, },
cacheTtlMs: 300_000,
}); });
export const umamiActiveVisitorsRequestHandler = createIntegrationRequestHandler< export const umamiActiveVisitorsRequestHandler = createIntegrationRequestHandler<
@@ -63,4 +68,5 @@ export const umamiActiveVisitorsRequestHandler = createIntegrationRequestHandler
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getActiveVisitorsAsync(input.websiteId); return await integrationInstance.getActiveVisitorsAsync(input.websiteId);
}, },
cacheTtlMs: 30_000,
}); });
+1
View File
@@ -13,4 +13,5 @@ export const upsSummariesRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getUpsSummariesAsync(); return await integrationInstance.getUpsSummariesAsync();
}, },
cacheTtlMs: 60_000,
}); });
@@ -12,4 +12,5 @@ export const uptimeKumaRequestHandler = createIntegrationRequestHandler<
const integrationInstance = await createIntegrationAsync(integration); const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getDashboardDataAsync(); return await integrationInstance.getDashboardDataAsync();
}, },
cacheTtlMs: 60_000,
}); });
+1
View File
@@ -25,4 +25,5 @@ export const vpnSummaryHandler = createIntegrationRequestHandler<
return null; return null;
} }
}, },
cacheTtlMs: 300_000,
}); });
+1
View File
@@ -31,6 +31,7 @@ export const weatherRequestHandler = createWidgetRequestHandler({
}), }),
} satisfies Weather; } satisfies Weather;
}, },
cacheTtlMs: 60_000,
}); });
const atLocationOutput = z.object({ const atLocationOutput = z.object({