mirror of
https://github.com/stablyai/orca.git
synced 2026-10-27 16:02:42 +00:00
perf(github): stop re-spawning the repo-identity probe every 30 seconds (#16450)
This commit is contained in:
@@ -61,6 +61,14 @@ export function ghRepoExecOptions(context: GitHubRepoContext): {
|
||||
|
||||
const OWNER_REPO_POSITIVE_CACHE_TTL_MS = 30_000
|
||||
const OWNER_REPO_NEGATIVE_CACHE_TTL_MS = 5 * 60_000
|
||||
/**
|
||||
* A signature-backed answer is held as long as a negative one. `git remote
|
||||
* get-url` reads `.git/config`, and the signature covers that file plus every
|
||||
* path it includes — so while the signature holds, a re-probe can only return
|
||||
* what is already cached. The short TTL above is the no-signature fallback
|
||||
* (remote runtimes, an unreadable gitdir), where nothing invalidates on change.
|
||||
*/
|
||||
const OWNER_REPO_SIGNED_CACHE_TTL_MS = 5 * 60_000
|
||||
const OWNER_REPO_CACHE_MAX_ENTRIES = 512
|
||||
|
||||
type OwnerRepoCacheEntry = {
|
||||
@@ -106,10 +114,10 @@ export async function getRemoteUrlForRepo(
|
||||
}
|
||||
|
||||
function getOwnerRepoCacheTtl(value: OwnerRepo | null, configSignature?: string): number {
|
||||
if (value) {
|
||||
return OWNER_REPO_POSITIVE_CACHE_TTL_MS
|
||||
if (configSignature) {
|
||||
return value ? OWNER_REPO_SIGNED_CACHE_TTL_MS : OWNER_REPO_NEGATIVE_CACHE_TTL_MS
|
||||
}
|
||||
return configSignature ? OWNER_REPO_NEGATIVE_CACHE_TTL_MS : OWNER_REPO_POSITIVE_CACHE_TTL_MS
|
||||
return OWNER_REPO_POSITIVE_CACHE_TTL_MS
|
||||
}
|
||||
|
||||
export async function getOwnerRepoForRemote(
|
||||
@@ -135,7 +143,11 @@ export async function getOwnerRepoForRemote(
|
||||
pruneOwnerRepoCache(now)
|
||||
const cached = ownerRepoCache.get(cacheKey)
|
||||
if (cached && cached.expiresAt > now) {
|
||||
if (cached.value === null && cached.configSignature !== undefined) {
|
||||
// Why every signed entry, not only the negatives: a positive identity is
|
||||
// held for the same five minutes now, so the same revalidation is what
|
||||
// keeps a `git remote set-url` visible within one lookup rather than five
|
||||
// minutes. The signature read is fs stat/readFile, not a Git subprocess.
|
||||
if (cached.configSignature !== undefined) {
|
||||
const currentSignature = await readLocalGitConfigSignature(context)
|
||||
if (currentSignature !== cached.configSignature) {
|
||||
ownerRepoCache.delete(cacheKey)
|
||||
@@ -203,9 +215,14 @@ async function resolveOwnerRepoForRemote(
|
||||
// Why: PR mutations need the effective host behind an SSH alias.
|
||||
const classification = await classifyGitHubOwnerRepoFromRemoteUrl(remoteUrl, context)
|
||||
if (classification.kind === 'github') {
|
||||
// Why store the signature: without it this entry can only expire on the
|
||||
// clock, which put a `git remote get-url` (plus its ssh-alias probe) on
|
||||
// every PR refresh cycle — the second most frequent Git subprocess in a
|
||||
// Windows field trace, on a host spawning Git at ~250-800ms a call.
|
||||
ownerRepoCache.set(cacheKey, {
|
||||
value: classification.ownerRepo,
|
||||
expiresAt: now + getOwnerRepoCacheTtl(classification.ownerRepo, configSignature)
|
||||
expiresAt: now + getOwnerRepoCacheTtl(classification.ownerRepo, configSignature),
|
||||
...(configSignature ? { configSignature } : {})
|
||||
})
|
||||
pruneOwnerRepoCache(now)
|
||||
return classification.ownerRepo
|
||||
|
||||
Reference in New Issue
Block a user