fix: honor signal refreshSec when caching signal reads

This commit is contained in:
LukeGus committed 2026-11-04 19:30:12 -06:00
1 parent 4aead47049
commit 2ee31ac9cc
3 files changed
+30 -1

No files matched your search

@@ -622,6 +622,7 @@ router.get("/signals", authenticateJWT, async (req, res) => {
userId: authReq.userId, userId: authReq.userId,
actionId: signal.read, actionId: signal.read,
hostIds, hostIds,
freshMs: signal.refreshSec ? signal.refreshSec * 1000 : undefined,
origin: originOf(authReq), origin: originOf(authReq),
}), }),
}); });
+5 -1
View File
@@ -78,6 +78,8 @@ interface ReadOptions {
actionId: string; actionId: string;
hostIds?: number[]; hostIds?: number[];
refresh?: boolean; refresh?: boolean;
/** How long a cached answer stays fresh. Defaults to RESOURCE_FRESH_MS. */
freshMs?: number;
input?: Record<string, unknown>; input?: Record<string, unknown>;
origin: ActorOrigin; origin: ActorOrigin;
} }
@@ -155,7 +157,9 @@ export async function readAcrossHosts<T>(
const key = cacheKey(options.userId, options.actionId, hostId); const key = cacheKey(options.userId, options.actionId, hostId);
const cached = cache.get(key); const cached = cache.get(key);
const fresh = cached && Date.now() - cached.fetchedAt < RESOURCE_FRESH_MS; const fresh =
cached &&
Date.now() - cached.fetchedAt < (options.freshMs ?? RESOURCE_FRESH_MS);
if (isOffline(hostId)) { if (isOffline(hostId)) {
reads.push({ reads.push({
@@ -275,3 +275,27 @@ describe("GET /operations/catalog", () => {
expect(response.body.actions).toEqual([{ id: "demo.restart" }]); expect(response.body.actions).toEqual([{ id: "demo.restart" }]);
}); });
}); });
describe("GET /operations/signals", () => {
it("keeps a signal's answer for its refreshSec", async () => {
const { buildCatalog } = await import("../../../operations/catalog.js");
const { readAcrossHosts } =
await import("../../../operations/resources.js");
vi.mocked(buildCatalog).mockResolvedValueOnce({
actions: [],
events: [],
resources: [],
signals: [
{ id: "a", read: "demo.a", scope: "host", refreshSec: 600 },
{ id: "b", read: "demo.b", scope: "host" },
],
} as never);
await request(app).get("/operations/signals").expect(200);
expect(vi.mocked(readAcrossHosts)).toHaveBeenCalledWith(
expect.objectContaining({ actionId: "demo.a", freshMs: 600_000 }),
);
expect(vi.mocked(readAcrossHosts)).toHaveBeenCalledWith(
expect.objectContaining({ actionId: "demo.b", freshMs: undefined }),
);
});
});