Skip to content

Commit 0c3d934

Browse files
committed
cache the betterstack response using unkey
1 parent 9f60ea4 commit 0c3d934

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

apps/webapp/app/routes/resources.incidents.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export async function loader() {
1717
}
1818

1919
return json({
20-
operational: result.data.data.attributes.aggregate_state === "operational",
20+
operational: result.data.attributes.aggregate_state === "operational",
2121
});
2222
}
2323

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { wrapZodFetch } from "@trigger.dev/core/v3/zodfetch";
1+
import { type ApiResult, wrapZodFetch } from "@trigger.dev/core/v3/zodfetch";
2+
import { createCache, DefaultStatefulContext, Namespace } from "@unkey/cache";
3+
import { MemoryStore } from "@unkey/cache/stores";
24
import { z } from "zod";
35
import { env } from "~/env.server";
46

@@ -14,6 +16,17 @@ const IncidentSchema = z.object({
1416

1517
export type Incident = z.infer<typeof IncidentSchema>;
1618

19+
const ctx = new DefaultStatefulContext();
20+
const memory = new MemoryStore({ persistentMap: new Map() });
21+
22+
const cache = createCache({
23+
query: new Namespace<ApiResult<Incident>>(ctx, {
24+
stores: [memory],
25+
fresh: 15_000,
26+
stale: 30_000,
27+
}),
28+
});
29+
1730
export class BetterStackClient {
1831
private readonly baseUrl = "https://uptime.betterstack.com/api/v2";
1932

@@ -28,27 +41,48 @@ export class BetterStackClient {
2841
return { success: false as const, error: "BETTERSTACK_STATUS_PAGE_ID is not set" };
2942
}
3043

31-
try {
32-
return await wrapZodFetch(
33-
IncidentSchema,
34-
`${this.baseUrl}/status-pages/${statusPageId}`,
35-
{
36-
headers: {
37-
Authorization: `Bearer ${apiKey}`,
38-
"Content-Type": "application/json",
39-
},
40-
},
41-
{
42-
retry: {
43-
maxAttempts: 3,
44-
minTimeoutInMs: 1000,
45-
maxTimeoutInMs: 5000,
44+
const cachedResult = await cache.query.swr("betterstack", async () => {
45+
try {
46+
const result = await wrapZodFetch(
47+
IncidentSchema,
48+
`${this.baseUrl}/status-pages/${statusPageId}`,
49+
{
50+
headers: {
51+
Authorization: `Bearer ${apiKey}`,
52+
"Content-Type": "application/json",
53+
},
4654
},
47-
}
48-
);
49-
} catch (error) {
50-
console.error("Failed to fetch incidents from BetterStack:", error);
51-
return { success: false as const, error };
55+
{
56+
retry: {
57+
maxAttempts: 3,
58+
minTimeoutInMs: 1000,
59+
maxTimeoutInMs: 5000,
60+
},
61+
}
62+
);
63+
64+
return result;
65+
} catch (error) {
66+
console.error("Failed to fetch incidents from BetterStack:", error);
67+
return {
68+
success: false as const,
69+
error: error instanceof Error ? error.message : "Unknown error",
70+
};
71+
}
72+
});
73+
74+
if (cachedResult.err) {
75+
return { success: false as const, error: cachedResult.err };
76+
}
77+
78+
if (!cachedResult.val) {
79+
return { success: false as const, error: "No result from BetterStack" };
5280
}
81+
82+
if (!cachedResult.val.success) {
83+
return { success: false as const, error: cachedResult.val.error };
84+
}
85+
86+
return { success: true as const, data: cachedResult.val.data.data };
5387
}
5488
}

0 commit comments

Comments
 (0)