mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-10-19 22:27:20 +02:00
fix: cancel token-gate waits and detect complete LFS prefixes
This commit is contained in:
1 parent
705f7c428a
commit
bfcea3e2b7
4 files changed
+113
-12
No files matched your search
+17
-3
@@ -15,6 +15,7 @@ import { getCredential, getCredentialToken } from "./credentials";
|
||||
import config from "../config";
|
||||
import { createLogger } from "./logger";
|
||||
import { measureStage } from "./request-monitoring";
|
||||
import { setTimeout as delay } from "timers/promises";
|
||||
|
||||
const logger = createLogger("github");
|
||||
|
||||
@@ -85,7 +86,18 @@ export function getTokenGateResetAt(token: string): number {
|
||||
return gate.resetAt;
|
||||
}
|
||||
|
||||
async function waitForTokenGate(token: string): Promise<void> {
|
||||
function abortableGateLookup(lookup: Promise<number>, signal: AbortSignal): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cancelled = () => { signal.removeEventListener("abort", cancelled); reject(signal.reason); };
|
||||
if (signal.aborted) cancelled();
|
||||
else signal.addEventListener("abort", cancelled, { once: true });
|
||||
lookup.then(value => { signal.removeEventListener("abort", cancelled); resolve(value); },
|
||||
error => { signal.removeEventListener("abort", cancelled); reject(error); });
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForTokenGate(token: string, signal?: AbortSignal): Promise<void> {
|
||||
signal?.throwIfAborted();
|
||||
const key = githubQuotaKey(token);
|
||||
const localGate = tokenGates.get(key);
|
||||
let waitMs = 0;
|
||||
@@ -96,7 +108,9 @@ async function waitForTokenGate(token: string): Promise<void> {
|
||||
waitMs = resetAt - Date.now();
|
||||
}
|
||||
|
||||
const redisResetAt = await getRedisGateResetAt(key);
|
||||
const lookup = getRedisGateResetAt(key);
|
||||
const redisResetAt = await (signal ? abortableGateLookup(lookup, signal) : lookup);
|
||||
signal?.throwIfAborted();
|
||||
if (redisResetAt > resetAt) {
|
||||
resetAt = redisResetAt;
|
||||
waitMs = resetAt - Date.now();
|
||||
@@ -112,7 +126,7 @@ async function waitForTokenGate(token: string): Promise<void> {
|
||||
waitMs,
|
||||
resetAt: new Date(resetAt).toISOString(),
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
||||
await delay(waitMs, undefined, { signal });
|
||||
if (localGate) tokenGates.delete(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ export default class GitHubStream extends GitHubBase {
|
||||
} catch (error) {
|
||||
if (!token || githubTokenContext(token)?.publicRepository ||
|
||||
(error as { response?: { statusCode?: number } }).response?.statusCode !== 404) throw error;
|
||||
await waitForTokenGate(token);
|
||||
await waitForTokenGate(token, cancellation.signal);
|
||||
const response = await octokit(token).repos.getContent({
|
||||
owner: data.organization, repo: data.repoName,
|
||||
path: filePath, ref: data.commit || "HEAD", mediaType: { format: "object" },
|
||||
@@ -186,7 +186,7 @@ export default class GitHubStream extends GitHubBase {
|
||||
if (checked) { yield chunk; continue; }
|
||||
probe = Buffer.concat([probe, Buffer.from(chunk)]);
|
||||
if (probe.length < 150) continue;
|
||||
if (probe.toString("utf8", 0, 39) === "version https://git-lfs.github.com/spec/") {
|
||||
if (probe.toString("utf8").startsWith("version https://git-lfs.github.com/spec/")) {
|
||||
throw new AnonymousError("upstream_error", { httpStatus: 502 });
|
||||
}
|
||||
checked = true; yield probe;
|
||||
@@ -294,7 +294,7 @@ export default class GitHubStream extends GitHubBase {
|
||||
probe = Buffer.concat([probe, bytes]);
|
||||
if (probe.length < 150) continue;
|
||||
decided = true;
|
||||
if (probe.toString("utf8", 0, 39) === "version https://git-lfs.github.com/spec/") {
|
||||
if (probe.toString("utf8").startsWith("version https://git-lfs.github.com/spec/")) {
|
||||
active = downloadRaw();
|
||||
for await (const raw of active) yield raw;
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user