[2.x] Reimplement FarmHash

**Problem**
sbtn and server uses FarmHash.

**Solution**
This reimplements FarmHash using Scala.
This commit is contained in:
Eugene Yokota
2026-05-31 16:57:12 -04:00
parent 82e5b28c9c
commit f1c914f4ae
13 changed files with 312 additions and 17 deletions
@@ -281,18 +281,18 @@ public class BootServerSocket implements AutoCloseable {
}
};
public BootServerSocket(final AppConfiguration configuration)
public BootServerSocket(final AppConfiguration configuration, final long farmHash)
throws ServerAlreadyBootingException, IOException {
final Path base = configuration.baseDirectory().toPath().toRealPath();
if (!isWindows) {
final String actualSocketLocation = socketLocation(base);
final String actualSocketLocation = socketLocation(base, farmHash);
final Path target = Paths.get(actualSocketLocation).getParent();
if (!Files.isDirectory(target)) Files.createDirectories(target);
socketFile = Paths.get(actualSocketLocation);
} else {
socketFile = null;
}
serverSocket = newSocket(socketLocation(base));
serverSocket = newSocket(socketLocation(base, farmHash));
if (serverSocket != null) {
running.set(true);
acceptFuture = service.submit(acceptRunnable);
@@ -302,20 +302,17 @@ public class BootServerSocket implements AutoCloseable {
}
}
public static String socketLocation(final Path base)
public static String socketLocation(final Path base, final long farmHash)
throws UnsupportedEncodingException, IOException {
final Path target = base.resolve("project").resolve("target");
long hash =
((long) target.toString().hashCode() << 32)
| (target.toString().length() * 31 & 0xffffffffL);
if (isWindows) {
return "sbt-load" + hash;
return "sbt-load" + farmHash;
} else {
final String alternativeSocketLocation =
System.getenv().getOrDefault("XDG_RUNTIME_DIR", System.getProperty("java.io.tmpdir"));
final Path alternativeSocketLocationRoot =
Paths.get(alternativeSocketLocation).resolve(".sbt");
final Path locationForSocket = alternativeSocketLocationRoot.resolve("sbt-socket" + hash);
final Path locationForSocket = alternativeSocketLocationRoot.resolve("sbt-socket" + farmHash);
final Path pathForSocket = locationForSocket.resolve("sbt-load.sock");
return pathForSocket.toString();
}
@@ -34,7 +34,7 @@ import sbt.internal.util.{
import sbt.io.IO
import sbt.io.syntax.*
import sbt.protocol.*
import sbt.util.{ Level, Logger }
import sbt.util.{ HashUtil, Level, Logger }
import sjsonnew.BasicJsonProtocol.*
import sjsonnew.shaded.scalajson.ast.unsafe.{ JObject, JValue }
import sjsonnew.support.scalajson.unsafe.Converter
@@ -341,8 +341,10 @@ class NetworkClient(
* This instance must be shutdown explicitly via `sbt -client shutdown`
*/
def waitForServer(portfile: File, log: Boolean, startServer: Boolean): Unit = {
val bootSocketName =
BootServerSocket.socketLocation(arguments.baseDirectory.toPath.toRealPath())
val base = arguments.baseDirectory.toPath.toRealPath()
val target = base.resolve("project").resolve("target")
val hash = HashUtil.farmHash(target.toString().getBytes("UTF-8"))
val bootSocketName = BootServerSocket.socketLocation(base, hash)
/*
* For unknown reasons, linux sometimes struggles to connect to the socket in some