mirror of
https://github.com/anuraghazra/github-readme-stats.git
synced 2024-11-27 05:30:32 +08:00
feat: rate limit error chaching (#2448)
* feat: rate limit error chaching Rate limit error caching to alleviate PATs. * refactor: improve code comments
This commit is contained in:
parent
64f56e88b4
commit
bc8eaecaf4
@ -77,7 +77,12 @@ export default async (req, res) => {
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ export default async (req, res) => {
|
||||
);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.FOUR_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
);
|
||||
@ -100,7 +100,12 @@ export default async (req, res) => {
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ export default async (req, res) => {
|
||||
const repoData = await fetchRepo(username, repo);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.FOUR_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
);
|
||||
@ -83,7 +83,12 @@ export default async (req, res) => {
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ export default async (req, res) => {
|
||||
);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.FOUR_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
);
|
||||
@ -99,7 +99,12 @@ export default async (req, res) => {
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
|
@ -42,7 +42,7 @@ export default async (req, res) => {
|
||||
const stats = await fetchWakatimeStats({ username, api_domain });
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.FOUR_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
);
|
||||
@ -50,10 +50,6 @@ export default async (req, res) => {
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
: cacheSeconds;
|
||||
|
||||
if (!cache_seconds) {
|
||||
cacheSeconds = CONSTANTS.FOUR_HOURS;
|
||||
}
|
||||
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
@ -82,7 +78,12 @@ export default async (req, res) => {
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
|
@ -72,5 +72,5 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
||||
}
|
||||
};
|
||||
|
||||
export { retryer };
|
||||
export { retryer, RETRIES };
|
||||
export default retryer;
|
||||
|
@ -373,11 +373,21 @@ const noop = () => {};
|
||||
const logger =
|
||||
process.env.NODE_ENV !== "test" ? console : { log: noop, error: noop };
|
||||
|
||||
// Cache settings.
|
||||
const CARD_CACHE_SECONDS = 14400;
|
||||
const ERROR_CACHE_SECONDS = 600;
|
||||
|
||||
const CONSTANTS = {
|
||||
ONE_MINUTE: 60,
|
||||
FIVE_MINUTES: 300,
|
||||
TEN_MINUTES: 600,
|
||||
FIFTEEN_MINUTES: 900,
|
||||
THIRTY_MINUTES: 1800,
|
||||
TWO_HOURS: 7200,
|
||||
FOUR_HOURS: 14400,
|
||||
ONE_DAY: 86400,
|
||||
CARD_CACHE_SECONDS,
|
||||
ERROR_CACHE_SECONDS,
|
||||
};
|
||||
|
||||
const SECONDARY_ERROR_MESSAGES = {
|
||||
|
@ -184,13 +184,18 @@ describe("Test /api/", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("should not store cache when error", async () => {
|
||||
it("should set shorter cache when error", async () => {
|
||||
const { req, res } = faker({}, error);
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
["Cache-Control", `no-cache, no-store, must-revalidate`],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import { retryer } from "../src/common/retryer.js";
|
||||
import { retryer, RETRIES } from "../src/common/retryer.js";
|
||||
import { logger } from "../src/common/utils.js";
|
||||
import { expect, it, describe } from "@jest/globals";
|
||||
|
||||
@ -44,7 +44,7 @@ describe("Test Retryer", () => {
|
||||
try {
|
||||
await retryer(fetcherFail, {});
|
||||
} catch (err) {
|
||||
expect(fetcherFail).toBeCalledTimes(8);
|
||||
expect(fetcherFail).toBeCalledTimes(RETRIES + 1);
|
||||
expect(err.message).toBe("Downtime due to GitHub API rate limiting");
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user