mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-14 16:07:52 +00:00
fix(java): keep a language server JDK that ran usable while it is unchanged (#2679)
A JDK whose java -version succeeded was probed again every 10 seconds; on a busy machine one probe could time out and the working JDK was reported as "cannot run on this machine". A successful probe now stays valid while the executable's size, modification time and permissions are unchanged; failed probes are still retried after 10 seconds, and a java that hangs on its first probe is still rejected. Fixes #2470
This commit is contained in:
@@ -64,7 +64,10 @@ pub(crate) fn java_runs(java: &Path) -> bool {
|
||||
&& probe.modified == modified
|
||||
&& probe.len == metadata.len()
|
||||
&& probe.permissions == metadata.permissions()
|
||||
&& probe.at.elapsed() < RESCAN_AFTER
|
||||
// An executable that ran keeps running while it is unchanged; probing it again
|
||||
// on a busy machine (jdtls indexing, an antivirus scan) can time out and turn
|
||||
// a working JDK into "cannot run" until the next probe.
|
||||
&& (probe.runnable || probe.at.elapsed() < RESCAN_AFTER)
|
||||
{
|
||||
return probe.runnable;
|
||||
}
|
||||
@@ -923,6 +926,33 @@ mod tests {
|
||||
assert_eq!(cfg.launch_error.as_deref(), Some("invalid selected JDK /outside/scan"));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn a_java_that_ran_is_not_probed_again_while_unchanged() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let jdk = test_jdk(tmp.path(), 25, "busy25");
|
||||
let java = java_executable(&jdk.home);
|
||||
let busy = tmp.path().join("busy");
|
||||
let probes = tmp.path().join("probes");
|
||||
// Times out once `busy` exists, as `java -version` can on a loaded machine.
|
||||
std::fs::write(
|
||||
&java,
|
||||
format!(
|
||||
"#!/bin/sh\necho >> '{}'\n[ -f '{}' ] && exec /bin/sleep 10\nexit 0\n",
|
||||
probes.display(),
|
||||
busy.display()
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(java_runs(&java));
|
||||
std::fs::write(&busy, "").unwrap();
|
||||
let long_ago = Instant::now().checked_sub(RESCAN_AFTER * 2).unwrap();
|
||||
JAVA_PROBES.lock().unwrap().get_mut(&java).unwrap().at = long_ago;
|
||||
assert!(java_runs(&java), "a JDK that ran stays usable");
|
||||
assert!(java_execution_error(&java).is_none());
|
||||
assert_eq!(std::fs::read_to_string(&probes).unwrap().lines().count(), 1, "probed once");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn slow_java_probe_does_not_hold_the_cache_lock() {
|
||||
|
||||
Reference in New Issue
Block a user