Skip to content

Commit 2b4a5c0

Browse files
committed
fix(mirror): seed "auto" so xlings' own region detection runs (remove curl probe)
Replaces the curl-based mcpp-side probe (per review: don't reinvent in mcpp; mirror selection is xlings' job, and it already does it via tinyhttps). Root cause of the repeated 75_index_status_offline.sh CI failures, now proven: mcpp seeded a hardcoded "CN" into a fresh .xlings.json. xlings' normalize_mirror_ accepts only "GLOBAL"/"CN" as valid, so "CN" was used DIRECTLY (gitcode) — bypassing xlings' own detect_install_mirror_(), which probes github vs gitcode latency (tinyhttps::probe_latency) and picks the reachable/faster region. On a GitHub-hosted (US) runner gitcode is slow/unreachable, so the cold index/sandbox bootstrap failed and the index reported 'missing'. Fix: seed "auto". normalize_mirror_("auto") -> nullopt (invalid) -> xlings treats the mirror as unset -> runs detect_install_mirror_() -> picks GLOBAL on a US runner, CN on a China link. mcpp no longer overrides xlings' region choice. The existing-config guard (config.cppm: only seed when .xlings.json is absent) already means an explicit `mcpp self config --mirror CN|GLOBAL` is never clobbered. Empirically confirmed via the curl-probe build's verbose CI run: on the US runner 'probe github=70ms gitcode=1060ms -> GLOBAL' then patchelf/ninja bootstrap succeeded and 75 PASSED — proving the mirror region is the cause. This commit hands that region choice back to xlings instead of doing it in mcpp.
1 parent 9d776f3 commit 2b4a5c0

2 files changed

Lines changed: 15 additions & 49 deletions

File tree

src/config.cppm

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,13 @@ bool write_default_xlings_json(const std::filesystem::path& path,
374374
// construct a temporary Env with home = path.parent_path().
375375
mcpp::xlings::Env env;
376376
env.home = path.parent_path();
377-
// No explicit --mirror: auto-detect the lower-latency reachable mirror
378-
// instead of the historic hardcoded "CN" (which strands overseas users and
379-
// GitHub-hosted CI). An explicit choice always wins (the else branch).
377+
// No explicit --mirror: seed "auto" so xlings' own adaptive mirror module
378+
// (latency-probed, with per-download failover) picks the best reachable
379+
// host. The historic hardcoded "CN" FORCED the CN mirror and disabled that
380+
// mechanism, stranding overseas users and GitHub-hosted CI on a
381+
// slow/unreachable gitcode. An explicit --mirror always wins (else branch).
380382
if (mirror_override.empty())
381-
mcpp::xlings::seed_xlings_json(env, pairs, mcpp::xlings::detect_best_mirror());
383+
mcpp::xlings::seed_xlings_json(env, pairs); // default = "auto"
382384
else
383385
mcpp::xlings::seed_xlings_json(env, pairs, mirror_override);
384386
return std::filesystem::exists(path);

src/xlings.cppm

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -225,24 +225,17 @@ int install_direct(const Env& env, std::string_view target, bool quiet = false);
225225

226226
// Write .xlings.json seed file.
227227
//
228-
// The `mirror` parameter still defaults to "CN" for direct callers, but the
229-
// first-init seed path (config.cppm) now passes the result of
230-
// `detect_best_mirror()` when the user gave no explicit `--mirror` — i.e.
231-
// TODO(mirror-default) option (b) is implemented: a quick latency probe to the
232-
// GLOBAL vs CN hosts picks the faster reachable one, so overseas users and
233-
// GitHub-hosted CI no longer get stranded on the historical CN default. An
234-
// explicit `mcpp self config --mirror X` always wins (config priority).
228+
// The `mirror` default is "auto": xlings' own adaptive mirror module
229+
// (xlings.core.mirror.adaptive — latency-probed with per-download failover and
230+
// failure penalisation) then picks the best reachable host per download. This
231+
// replaces the historic hardcoded "CN", which FORCED the CN mirror and disabled
232+
// that mechanism — stranding overseas users and GitHub-hosted CI on a
233+
// slow/unreachable gitcode. An explicit `mcpp self config --mirror CN|GLOBAL`
234+
// still writes that fixed value (config priority). Mirror selection is xlings'
235+
// responsibility; mcpp just declines to override it by default.
235236
void seed_xlings_json(const Env& env,
236237
std::span<const std::pair<std::string,std::string>> repos,
237-
std::string_view mirror = "CN");
238-
239-
// Probe both index mirrors and return the lower-latency reachable one
240-
// ("GLOBAL" | "CN") — TODO(mirror-default) option (b). Used at first init when
241-
// the user gave no explicit --mirror; an explicit choice always wins (config
242-
// priority). Falls back to "GLOBAL" (reachable nearly everywhere) when neither
243-
// probe succeeds, since the historic "CN" default stranded overseas users and
244-
// GitHub-hosted CI behind a slow/unreachable mirror.
245-
std::string detect_best_mirror();
238+
std::string_view mirror = "auto");
246239

247240
// Persist the xlings mirror selection in .xlings.json via xlings itself.
248241
int config_show(const Env& env);
@@ -1094,35 +1087,6 @@ void seed_xlings_json(const Env& env,
10941087
write_file(path, json);
10951088
}
10961089

1097-
std::string detect_best_mirror() {
1098-
using namespace std::chrono;
1099-
// A short HEAD probe to each mirror host, timed by wall clock. Non-zero rc
1100-
// (DNS failure, connection refused, or the tight --max-time elapsing) means
1101-
// "unreachable". curl is present on every platform mcpp targets; if it is
1102-
// somehow absent both probes fail and we fall back to GLOBAL.
1103-
auto probe = [](std::string_view url) -> std::optional<double> {
1104-
// -I writes response headers to stdout; redirect both streams to null
1105-
// (cross-platform) so the probe stays silent — only its timing matters.
1106-
auto cmd = std::format("curl -s -I --max-time 3 {} {}",
1107-
url, mcpp::platform::shell::silent_redirect);
1108-
auto t0 = steady_clock::now();
1109-
if (mcpp::platform::process::run_silent(cmd) != 0) return std::nullopt;
1110-
return duration<double>(steady_clock::now() - t0).count();
1111-
};
1112-
auto g = probe("https://github.com");
1113-
auto c = probe("https://gitcode.com");
1114-
if (g && c) {
1115-
std::string pick = (*g <= *c) ? "GLOBAL" : "CN";
1116-
mcpp::log::verbose("mirror", std::format(
1117-
"probe github={:.0f}ms gitcode={:.0f}ms -> {}", *g * 1000, *c * 1000, pick));
1118-
return pick;
1119-
}
1120-
if (g) { mcpp::log::verbose("mirror", "only github reachable -> GLOBAL"); return "GLOBAL"; }
1121-
if (c) { mcpp::log::verbose("mirror", "only gitcode reachable -> CN"); return "CN"; }
1122-
mcpp::log::verbose("mirror", "neither mirror reachable; defaulting -> GLOBAL");
1123-
return "GLOBAL";
1124-
}
1125-
11261090
int config_show(const Env& env) {
11271091
auto cmd = std::format("{} config", build_command_prefix(env));
11281092
return mcpp::platform::process::run_silent(cmd);

0 commit comments

Comments
 (0)