mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 16:02:24 +00:00
104 lines
4.5 KiB
Diff
104 lines
4.5 KiB
Diff
diff --git a/src/main/gitlab/gitlab-known-host-probe.ts b/src/main/gitlab/gitlab-known-host-probe.ts
|
|
index 752e1b0291..d328cd38ca 100644
|
|
--- a/src/main/gitlab/gitlab-known-host-probe.ts
|
|
+++ b/src/main/gitlab/gitlab-known-host-probe.ts
|
|
@@ -12,7 +12,10 @@ export type LocalGitExecOptions = {
|
|
|
|
const GLAB_KNOWN_HOSTS_TIMEOUT_MS = 10_000
|
|
const UNAUTHENTICATED_HOSTS_MAX_ENTRIES = 128
|
|
-const knownHostsCacheByExecutionContext = new Map<string, readonly string[]>()
|
|
+const knownHostsCacheByExecutionContext = new Map<
|
|
+ string,
|
|
+ { key: string; hosts: readonly string[] }
|
|
+>()
|
|
const knownHostsInFlightByExecutionContext: CoalescedProbes<readonly string[]> = new Map()
|
|
const unauthenticatedHostExpiries = new Map<string, number>()
|
|
|
|
@@ -27,6 +30,19 @@ function knownHostsExecutionKey(
|
|
return localGitOptions.wslDistro ? `wsl:${localGitOptions.wslDistro}` : 'native'
|
|
}
|
|
|
|
+function knownHostsCacheContext(
|
|
+ connectionId?: string | null,
|
|
+ localGitOptions: LocalGitExecOptions = {}
|
|
+): { key: string; cacheKey: string } {
|
|
+ const key = knownHostsExecutionKey(connectionId, localGitOptions)
|
|
+ const cacheKey = connectionId ? `connection:${connectionId}` : key
|
|
+ const cached = knownHostsCacheByExecutionContext.get(cacheKey)
|
|
+ if (cached && cached.key !== key) {
|
|
+ knownHostsCacheByExecutionContext.delete(cacheKey)
|
|
+ }
|
|
+ return { key, cacheKey }
|
|
+}
|
|
+
|
|
/** @internal - exposed for tests only */
|
|
export function _resetKnownHostsCache(): void {
|
|
knownHostsCacheByExecutionContext.clear()
|
|
@@ -103,8 +119,8 @@ export function rememberGlabKnownHosts(
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): void {
|
|
- const key = knownHostsExecutionKey(connectionId, localGitOptions)
|
|
- const cached = knownHostsCacheByExecutionContext.get(key) ?? DEFAULT_GITLAB_HOSTS
|
|
+ const { key, cacheKey } = knownHostsCacheContext(connectionId, localGitOptions)
|
|
+ const cached = knownHostsCacheByExecutionContext.get(cacheKey)?.hosts ?? DEFAULT_GITLAB_HOSTS
|
|
const seen = new Set(cached.map(normalizeGitLabHost))
|
|
const additions: string[] = []
|
|
for (const host of hosts) {
|
|
@@ -121,27 +137,29 @@ export function rememberGlabKnownHosts(
|
|
if (additions.length === 0) {
|
|
return
|
|
}
|
|
- knownHostsCacheByExecutionContext.set(key, [...cached, ...additions])
|
|
+ knownHostsCacheByExecutionContext.set(cacheKey, { key, hosts: [...cached, ...additions] })
|
|
}
|
|
|
|
export async function getGlabKnownHosts(
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<readonly string[]> {
|
|
- const key = knownHostsExecutionKey(connectionId, localGitOptions)
|
|
- const cached = knownHostsCacheByExecutionContext.get(key)
|
|
+ const { key, cacheKey } = knownHostsCacheContext(connectionId, localGitOptions)
|
|
+ const cached = knownHostsCacheByExecutionContext.get(cacheKey)?.hosts
|
|
if (cached) {
|
|
return cached
|
|
}
|
|
// Why: only join a probe still young enough to answer, so a wedged one cannot
|
|
// pin every later retry for the life of the process (P1-D).
|
|
- return runCoalescedProbe(knownHostsInFlightByExecutionContext, key, () =>
|
|
- probeGlabKnownHosts(key, connectionId, localGitOptions)
|
|
+ return runCoalescedProbe(knownHostsInFlightByExecutionContext, key, (ownsKey) =>
|
|
+ probeGlabKnownHosts(key, cacheKey, ownsKey, connectionId, localGitOptions)
|
|
)
|
|
}
|
|
|
|
async function probeGlabKnownHosts(
|
|
key: string,
|
|
+ cacheKey: string,
|
|
+ ownsKey: () => boolean,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<readonly string[]> {
|
|
@@ -160,13 +178,17 @@ async function probeGlabKnownHosts(
|
|
...(localGitOptions.admissionTier ? { admissionTier: localGitOptions.admissionTier } : {})
|
|
})
|
|
const hosts = parseGlabAuthStatusHosts(`${stdout}\n${stderr}`)
|
|
- const remembered = knownHostsCacheByExecutionContext.get(key) ?? []
|
|
+ const cached = knownHostsCacheByExecutionContext.get(cacheKey)
|
|
+ const remembered = cached?.key === key ? cached.hosts : []
|
|
const merged = Array.from(new Set([...DEFAULT_GITLAB_HOSTS, ...remembered, ...hosts]))
|
|
- knownHostsCacheByExecutionContext.set(key, merged)
|
|
+ if (ownsKey() && knownHostsExecutionKey(connectionId, localGitOptions) === key) {
|
|
+ knownHostsCacheByExecutionContext.set(cacheKey, { key, hosts: merged })
|
|
+ }
|
|
return merged
|
|
} catch {
|
|
// Keep failures uncached so auth or tunnel recovery is discovered later.
|
|
- return knownHostsCacheByExecutionContext.get(key) ?? [...DEFAULT_GITLAB_HOSTS]
|
|
+ const cached = knownHostsCacheByExecutionContext.get(cacheKey)
|
|
+ return cached?.key === key ? cached.hosts : [...DEFAULT_GITLAB_HOSTS]
|
|
}
|
|
}
|
|
|