diff options
-rw-r--r-- | src/main/cpp/blaze.cc | 38 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/server/GrpcServerImpl.java | 54 |
2 files changed, 47 insertions, 45 deletions
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 438253422a..0b22226aac 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -711,7 +711,7 @@ static void SetRestartReasonIfNotSet(RestartReason restart_reason) { } } -// Starts up a new server and connects to it. Exits if it didn't work not. +// Starts up a new server and connects to it. Exits if it didn't work out. static void StartServerAndConnect(const WorkspaceLayout *workspace_layout, BlazeServer *server) { string server_dir = @@ -1077,9 +1077,9 @@ static void EnsureCorrectRunningVersion(BlazeServer *server) { globals->options->install_base)) { if (server->Connected()) { server->KillRunningServer(); + globals->restart_reason = NEW_VERSION; } - globals->restart_reason = NEW_VERSION; blaze_util::UnlinkPath(installation_path); if (!SymlinkDirectories(globals->options->install_base, installation_path)) { @@ -1444,6 +1444,16 @@ bool GrpcBlazeServer::Connect() { return false; } + pid_t server_pid = GetServerPid(server_dir); + if (server_pid < 0) { + return false; + } + + if (!VerifyServerProcess(server_pid, globals->options->output_base, + globals->options->install_base)) { + return false; + } + std::shared_ptr<grpc::Channel> channel( grpc::CreateChannel(port, grpc::InsecureChannelCredentials())); std::unique_ptr<command_server::CommandServer::Stub> client( @@ -1455,29 +1465,7 @@ bool GrpcBlazeServer::Connect() { this->client_ = std::move(client); connected_ = true; - - globals->server_pid = GetServerPid(server_dir); - if (globals->server_pid <= 0) { - fprintf(stderr, - "Can't get PID of existing server (server dir=%s). " - "Shutting it down and starting a new one...\n", - server_dir.c_str()); - // This means that we have a server we could connect to but without a PID - // file, which in turn means that something went wrong before. Kill the - // server so that we can start with as clean a slate as possible. This may - // happen if someone (e.g. a client or server that's very old and uses an - // AF_UNIX socket instead of gRPC) deletes the server.pid.txt file. - KillRunningServer(); - // Then wait until it actually dies - do { - auto next_attempt_time(std::chrono::system_clock::now() + - std::chrono::milliseconds(1000)); - std::this_thread::sleep_until(next_attempt_time); - } while (TryConnect(client_.get())); - - return false; - } - + globals->server_pid = server_pid; return true; } 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 676337e8c6..d9689baaa1 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 @@ -54,8 +54,10 @@ import java.io.StringWriter; import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.security.SecureRandom; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.Exchanger; @@ -528,15 +530,23 @@ public class GrpcServerImpl implements RPCServer { private IdleServerTasks idleServerTasks; private final int port; boolean serving; + private List<Path> filesToDeleteAtExit = new ArrayList<Path>(); public GrpcServerImpl(CommandExecutor commandExecutor, Clock clock, int port, Path workspace, Path serverDirectory, int maxIdleSeconds) throws IOException { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + shutdownHook(); + } + }); + // server.pid was written in the C++ launcher after fork() but before exec() . // The client only accesses the pid file after connecting to the socket // which ensures that it gets the correct pid value. pidFile = serverDirectory.getRelative("server.pid.txt"); pidInFile = new String(FileSystemUtils.readContentAsLatin1(pidFile)); - deleteAtExit(pidFile, /*deleteParent=*/ false); + deleteAtExit(pidFile); this.commandExecutor = commandExecutor; this.clock = clock; @@ -749,34 +759,38 @@ public class GrpcServerImpl implements RPCServer { private void writeServerFile(String name, String contents) throws IOException { Path file = serverDirectory.getChild(name); FileSystemUtils.writeContentAsLatin1(file, contents); - deleteAtExit(file, false); + deleteAtExit(file); } protected void disableShutdownHooks() { runShutdownHooks.set(false); } + private void shutdownHook() { + if (!runShutdownHooks.get()) { + return; + } + + List<Path> files; + synchronized (filesToDeleteAtExit) { + files = new ArrayList<>(filesToDeleteAtExit); + } + for (Path path : files) { + try { + path.delete(); + } catch (IOException e) { + printStack(e); + } + } + } + /** * Schedule the specified file for (attempted) deletion at JVM exit. */ - protected static void deleteAtExit(final Path path, final boolean deleteParent) { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - if (!runShutdownHooks.get()) { - return; - } - - try { - path.delete(); - if (deleteParent) { - path.getParentDirectory().delete(); - } - } catch (IOException e) { - printStack(e); - } - } - }); + protected void deleteAtExit(final Path path) { + synchronized (filesToDeleteAtExit) { + filesToDeleteAtExit.add(path); + } } static void printStack(IOException e) { |