Skip to content

Commit

Permalink
chore: attempt at caching only after response is sent
Browse files Browse the repository at this point in the history
  • Loading branch information
alfetopito committed Apr 30, 2024
1 parent 55387a7 commit b2dd0eb
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
27 changes: 20 additions & 7 deletions src/routes/coingeckoProxy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fastifyCaching from "@fastify/caching";
import httpProxy from "@fastify/http-proxy";
import { FastifyPluginAsync } from "fastify";
import { ReadableStream } from "stream/web";
import payloadDataReply from "./payloadDataReply";

const CACHE_TTL = 1 * 60; // 1 min in s
const SERVER_CACHE_TTL = 1.5 * 60; // 1.5 min in s
Expand Down Expand Up @@ -47,13 +48,14 @@ const coingeckoProxy: FastifyPluginAsync = async (
if (isCachedResponse(result)) {
fastify.log.info(`onRequest: cache hit for ${req.url}`);
reply
.headers({ "cache-hit": true, ...result.item.headers })
.headers({ ...result.item.headers, "x-proxy-cache": "HIT" })
.send(result.item.contents);
}
});
});

// Intercepts response to store result on cache
fastify.register(payloadDataReply);

fastify.addHook("onSend", async function (req, reply, payload) {
// Apply our own cache control header, but only if set in the response already
if (reply.getHeader("cache-control")) {
Expand All @@ -63,11 +65,22 @@ const coingeckoProxy: FastifyPluginAsync = async (
);
}

if (reply.getHeader("cache-hit")) {
// Header set when there's a cache hit, remove it
reply.removeHeader("cache-hit");
} else if (reply.statusCode >= 200 && reply.statusCode < 300) {
fastify.log.info(`onSend: caching response for ${req.url}`);
if (!reply.getHeader("x-proxy-cache")) {
reply.header("x-proxy-cache", "MISS");
}
});

// After the response is sent, cache it if needed
fastify.addHook("onRequest", async function (req, reply) {
const payload = "payloadData" in reply && reply.payloadData;

if (
reply.getHeader("x-proxy-cache") === "MISS" &&
reply.statusCode >= 200 &&
reply.statusCode < 300 &&
payload
) {
fastify.log.info(`onRequest: caching response for ${req.url}`);

// No cache hit, consume the payload stream to be able to cache it
let contents = "";
Expand Down
23 changes: 23 additions & 0 deletions src/routes/coingeckoProxy/payloadDataReply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FastifyPluginAsync } from "fastify";

const plugin: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.decorateReply("payloadData", null);

fastify.addHook("onSend", function (req, reply, payload) {
console.log("onSend:payloadData");
fastify.payloadData = payload;
console.log("onSend:payloadData");
});
};

declare module "fastify" {
export interface FastifyInstance {
/**
* `payload` is only populated after `onSend` hook
* To be consumed inside `onRequest` hook
*/
payloadData?: unknown;
}
}

export default plugin;

0 comments on commit b2dd0eb

Please # to comment.