diff --git a/src/main/java/com/google/devtools/build/lib/server/GrpcServerImpl.java b/src/main/java/com/google/devtools/build/lib/server/GrpcServerImpl.java index 8efb5da16d3473..c7c21960e63f6e 100644 --- a/src/main/java/com/google/devtools/build/lib/server/GrpcServerImpl.java +++ b/src/main/java/com/google/devtools/build/lib/server/GrpcServerImpl.java @@ -46,6 +46,7 @@ import com.google.devtools.build.lib.util.DetailedExitCode; import com.google.devtools.build.lib.util.ExitCode; import com.google.devtools.build.lib.util.InterruptedFailureDetails; +import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.io.OutErr; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -376,6 +377,26 @@ public void interrupt() { commandManager.interruptInflightCommands(); } + private Server bindIpv6WithRetries(InetSocketAddress address, int maxRetries) throws IOException { + Server server = null; + for (int attempt = 1; attempt <= maxRetries; attempt++) { + try { + server = + NettyServerBuilder.forAddress(address) + .addService(this) + .directExecutor() + .build() + .start(); + break; + } catch (IOException e) { + if (attempt == maxRetries) { + throw e; + } + } + } + return server; + } + @Override public void serve() throws AbruptExitException { Preconditions.checkState(!serving); @@ -391,8 +412,10 @@ public void serve() throws AbruptExitException { if (Epoll.isAvailable() && !Socket.isIPv6Preferred()) { throw new IOException("ipv6 is not preferred on the system."); } - server = - NettyServerBuilder.forAddress(address).addService(this).directExecutor().build().start(); + // For some strange reasons, Bazel server sometimes fails to bind to IPv6 localhost when + // running in macOS sandbox-exec with internet blocked. Retrying seems to help. + // See https://github.com/bazelbuild/bazel/issues/20743 + server = bindIpv6WithRetries(address, OS.getCurrent() == OS.DARWIN ? 3 : 1); } catch (IOException ipv6Exception) { address = new InetSocketAddress("127.0.0.1", port); try {