Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/app/lib/utilities/getEnvConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export const getProcessEnvAppVariables = () => ({
process.env.SIMORGH_WEBVITALS_REPORTING_ENDPOINT,
SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE:
process.env.SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE,
SIMORGH_BFF_CACHE_ITEMS: process.env.SIMORGH_BFF_CACHE_ITEMS,
SIMORGH_BFF_CACHE_MAX_AGE_SECONDS:
process.env.SIMORGH_BFF_CACHE_MAX_AGE_SECONDS,
});

export function getEnvConfig(): EnvConfig {
Expand Down
6 changes: 6 additions & 0 deletions src/app/routes/utils/fetchDataFromBFF/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { BFF_FETCH_ERROR } from '#lib/logger.const';
import { FetchError, GetAgent } from '#models/types/fetch';
import nodeLogger from '#lib/logger.node';
import certsRequired from '#app/routes/utils/certsRequired';
import type { LRUCache } from 'lru-cache';

type BffCache = LRUCache<string, Record<string, unknown>>;

const logger = nodeLogger(__filename);

Expand All @@ -19,6 +22,7 @@ interface FetchDataFromBffParams {
disableRadioSchedule?: boolean;
page?: string;
getAgent?: GetAgent;
cache?: BffCache;
}

export default async ({
Expand All @@ -30,6 +34,7 @@ export default async ({
disableRadioSchedule,
page,
getAgent,
cache,
}: FetchDataFromBffParams) => {
const environment = getEnvironment(pathname);

Expand Down Expand Up @@ -58,6 +63,7 @@ export default async ({
...(agent && { agent }),
...(optHeaders && { optHeaders }),
...(timeout && { timeout }),
...(cache && { cache }),
};

// @ts-expect-error - Ignore fetchPageData argument types
Expand Down
25 changes: 24 additions & 1 deletion ws-nextjs-app/utilities/pageRequests/getPageData.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LRUCache } from 'lru-cache';
import { BFF_FETCH_ERROR } from '#app/lib/logger.const';
import getToggles from '#app/lib/utilities/getToggles/withCache';
import { FetchError } from '#app/models/types/fetch';
Expand All @@ -10,6 +11,25 @@ import { PageTypes, Services, Variants } from '#app/models/types/global';

const logger = nodeLogger(__filename);

// cache holds the raw bff json; keep it loose because payloads vary by page type
type BffCacheValue = Record<string, unknown>;

// read numeric envs with a simple fallback; keeps memory low by default
const BFF_CACHE_MAX_ITEMS =
Number.parseInt(process.env.SIMORGH_BFF_CACHE_ITEMS ?? '', 10) || 200;
// one minute ttl to help quick repeat requests without risking stale data
const BFF_CACHE_TTL_MS =
(Number.parseInt(
process.env.SIMORGH_BFF_CACHE_MAX_AGE_SECONDS ?? '',
10,
) || 60) * 1000;

// cache lives inside this server process
const bffCache = new LRUCache<string, BffCacheValue>({
max: BFF_CACHE_MAX_ITEMS,
ttl: BFF_CACHE_TTL_MS,
});

type Props = {
id?: string;
page?: string;
Expand All @@ -36,6 +56,8 @@ const getPageData = async ({
const rendererEnvironment = url.searchParams.get('renderer_env');
const pathname = `${id}${rendererEnvironment ? `?renderer_env=${rendererEnvironment}` : ''}`;

const togglesPromise = getToggles(service);

let message;
let status;
let json;
Expand All @@ -49,6 +71,7 @@ const getPageData = async ({
page,
getAgent,
isAmp,
cache: bffCache,
}));
} catch (error: unknown) {
({ message, status } = error as FetchError);
Expand All @@ -72,7 +95,7 @@ const getPageData = async ({
? { pageData: json.data, status }
: { error: message, status };

const toggles = await getToggles(service);
const toggles = await togglesPromise;

return { data, toggles };
};
Expand Down
Loading