Skip to content

Commit 9d36622

Browse files
committed
Cache the apiCategories() method using a promise
Commit 680c7c4 added memoized the fetch for OpenAPI JSON in the `resolveOpenAPI` function, but that particular implementation caused some problems with the build output. Some of the pages in the API section went missing. The previous implementation was susceptible to a bit of a race condition, since the cached value wasn't set until after several async calls. When Next tries to aggressively build pages, multiple calls could have gotten through to do live calls, and then all of them would have tried to set the cache variable. I don't know the exact pathway to the issue but I suspect this had something to do with the missing pages (some sort of data corruption?). Sorry, I know this is handwavy. Anyway, replacing that implementation with a more robust one - one that caches a promise on the first call, and reuses that promise on all future calls - will definitely only fetch once per process. When the fetch completes, everyone waiting on the promise will awaken, and then future callers of the method will get a resolved promise for immediate results. And, most importantly, this method of caching doesn't cause the `api/auth` and `api/guides` pages to go missing.
1 parent de02806 commit 9d36622

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/build/resolveOpenAPI.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import {promises as fs} from 'fs';
66

7-
import {cache} from 'react';
8-
97
import {DeRefedOpenAPI} from './open-api/types';
108

119
// SENTRY_API_SCHEMA_SHA is used in the sentry-docs GHA workflow in getsentry/sentry-api-schema.
@@ -77,7 +75,18 @@ function slugify(s: string): string {
7775
.toLowerCase();
7876
}
7977

80-
export const apiCategories = cache(async (): Promise<APICategory[]> => {
78+
let apiCategoriesCache: Promise<APICategory[]> | undefined;
79+
80+
export function apiCategories(): Promise<APICategory[]> {
81+
if (apiCategoriesCache) {
82+
return apiCategoriesCache;
83+
}
84+
apiCategoriesCache = apiCategoriesUncached();
85+
return apiCategoriesCache;
86+
}
87+
88+
async function apiCategoriesUncached(): Promise<APICategory[]> {
89+
console.log('apiCategories');
8190
const data = await resolveOpenAPI();
8291

8392
const categoryMap: {[name: string]: APICategory} = {};
@@ -142,7 +151,7 @@ export const apiCategories = cache(async (): Promise<APICategory[]> => {
142151
c.apis.sort((a, b) => a.name.localeCompare(b.name));
143152
});
144153
return categories;
145-
});
154+
}
146155

147156
function getBodyParameters(apiData): APIParameter[] {
148157
const content = apiData.requestBody?.content;

0 commit comments

Comments
 (0)