aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/RmiJmxConnector.java2
-rw-r--r--server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/TerminatorThread.java1
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java12
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java10
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java10
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/test/HttpProcess.java18
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/test/StandardProcess.java5
-rw-r--r--server/sonar-search/src/main/java/org/sonar/search/SearchServer.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java83
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java5
10 files changed, 87 insertions, 72 deletions
diff --git a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/RmiJmxConnector.java b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/RmiJmxConnector.java
index ec8dba2902a..876ccc2b22f 100644
--- a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/RmiJmxConnector.java
+++ b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/RmiJmxConnector.java
@@ -19,6 +19,7 @@
*/
package org.sonar.process.monitor;
+import org.slf4j.LoggerFactory;
import org.sonar.process.JmxUtils;
import org.sonar.process.LoopbackAddress;
import org.sonar.process.ProcessMXBean;
@@ -92,6 +93,7 @@ class RmiJmxConnector implements JmxConnector {
execute(new Callable() {
@Override
public Void call() throws Exception {
+ LoggerFactory.getLogger(getClass()).info("Request termination of " + processRef);
mbeans.get(processRef).terminate();
return null;
}
diff --git a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/TerminatorThread.java b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/TerminatorThread.java
index f0943086877..f5b11b3148f 100644
--- a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/TerminatorThread.java
+++ b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/TerminatorThread.java
@@ -48,7 +48,6 @@ class TerminatorThread extends Thread {
final ProcessRef processRef = processes.get(index);
if (!processRef.isTerminated()) {
processRef.setPingEnabled(false);
-
try {
jmxConnector.terminate(processRef, timeouts.getTerminationTimeout());
} catch (Exception ignored) {
diff --git a/server/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java b/server/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java
index 6ee84d00744..11ddf54beec 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java
@@ -22,10 +22,20 @@ package org.sonar.process;
public interface MonitoredProcess extends Terminable {
/**
- * Starts and blocks until ready
+ * Starts process. No need to block until fully started and operational.
*/
void start();
+ /**
+ * True if the process is started and operational (-> can accept requests), false if
+ * it's still starting. An exception is thrown is process failed to start (not starting
+ * nor started).
+ */
+ boolean isReady();
+
+ /**
+ * Blocks until the process is terminated
+ */
void awaitTermination();
}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
index 6990545a571..7137a41fa12 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
@@ -75,10 +75,17 @@ public class ProcessEntryPoint implements ProcessMXBean {
try {
monitoredProcess.start();
+ boolean ready = false;
+ while (!ready) {
+ ready = monitoredProcess.isReady();
+ Thread.sleep(200L);
+ }
if (lifecycle.tryToMoveTo(State.STARTED)) {
monitoredProcess.awaitTermination();
}
- } catch (Exception ignored) {
+ } catch (Exception e) {
+ LoggerFactory.getLogger(getClass()).warn("Fail to start", e);
+
} finally {
terminate();
}
@@ -86,7 +93,6 @@ public class ProcessEntryPoint implements ProcessMXBean {
@Override
public boolean isReady() {
- LoggerFactory.getLogger(getClass()).warn("Received JMX request isReady: " + (lifecycle.getState() == State.STARTED));
return lifecycle.getState() == State.STARTED;
}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
index 55bf8d679d1..03cd7409a49 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
@@ -194,6 +194,11 @@ public class ProcessEntryPointTest {
}
@Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
public void awaitTermination() {
}
@@ -212,6 +217,11 @@ public class ProcessEntryPointTest {
}
@Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
public void awaitTermination() {
}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/test/HttpProcess.java b/server/sonar-process/src/test/java/org/sonar/process/test/HttpProcess.java
index 307abed6d0b..f6ca587a588 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/test/HttpProcess.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/test/HttpProcess.java
@@ -42,6 +42,7 @@ import java.io.IOException;
public class HttpProcess implements MonitoredProcess {
private final Server server;
+ private boolean ready = false;
// temp dir is specific to this process
private final File tempDir = new File(System.getProperty("java.io.tmpdir"));
@@ -70,17 +71,24 @@ public class HttpProcess implements MonitoredProcess {
});
try {
server.start();
- while (!server.isStarted()) {
- Thread.sleep(100L);
- }
- writeTimeToFile("readyAt");
-
} catch (Exception e) {
throw new IllegalStateException("Fail to start Jetty", e);
}
}
@Override
+ public boolean isReady() {
+ if (ready) {
+ return true;
+ }
+ if (server.isStarted()) {
+ ready = true;
+ writeTimeToFile("readyAt");
+ }
+ return false;
+ }
+
+ @Override
public void awaitTermination() {
try {
server.join();
diff --git a/server/sonar-process/src/test/java/org/sonar/process/test/StandardProcess.java b/server/sonar-process/src/test/java/org/sonar/process/test/StandardProcess.java
index 121784f633b..4c1a33221c6 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/test/StandardProcess.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/test/StandardProcess.java
@@ -51,6 +51,11 @@ public class StandardProcess implements MonitoredProcess {
}
@Override
+ public boolean isReady() {
+ return state == State.STARTED;
+ }
+
+ @Override
public void awaitTermination() {
try {
daemon.join();
diff --git a/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java b/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java
index cf7eb1682df..d2aa111e7e5 100644
--- a/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java
+++ b/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java
@@ -143,20 +143,11 @@ public class SearchServer implements MonitoredProcess {
.setTemplate("*")
.addMapping("_default_", "{\"dynamic\": \"strict\"}")
.get();
-
- boolean ready = false;
- while (!ready) {
- ready = isReady();
- try {
- Thread.sleep(300L);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
}
}
- boolean isReady() {
+ @Override
+ public boolean isReady() {
return node.client().admin().cluster().prepareHealth()
.setWaitForYellowStatus()
.setTimeout(TimeValue.timeValueSeconds(3L))
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
index a7146eda913..01a5305c53d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
@@ -20,16 +20,7 @@
package org.sonar.server.app;
import com.google.common.base.Throwables;
-import com.google.common.util.concurrent.Uninterruptibles;
-import org.apache.catalina.Container;
-import org.apache.catalina.Executor;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.LifecycleState;
-import org.apache.catalina.Server;
-import org.apache.catalina.Service;
-import org.apache.catalina.connector.Connector;
+import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.io.FileUtils;
@@ -37,13 +28,11 @@ import org.slf4j.LoggerFactory;
import org.sonar.process.Props;
import java.io.File;
-import java.util.concurrent.TimeUnit;
class EmbeddedTomcat {
private final Props props;
private Tomcat tomcat = null;
- private Thread hook = null;
private volatile StandardContext webappContext;
EmbeddedTomcat(Props props) {
@@ -51,53 +40,43 @@ class EmbeddedTomcat {
}
void start() {
- if (tomcat != null || hook != null) {
- throw new IllegalStateException("Server is already started");
- }
-
- try {
- // '%2F' (slash /) and '%5C' (backslash \) are permitted as path delimiters in URLs
- // See Ruby on Rails url_for
- System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
+ // '%2F' (slash /) and '%5C' (backslash \) are permitted as path delimiters in URLs
+ // See Ruby on Rails url_for
+ System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
- System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
+ System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
- tomcat = new Tomcat();
- // Initialize directories
- String basedir = tomcatBasedir().getAbsolutePath();
- tomcat.setBaseDir(basedir);
- tomcat.getHost().setAppBase(basedir);
- tomcat.getHost().setAutoDeploy(false);
- tomcat.getHost().setCreateDirs(false);
- tomcat.getHost().setDeployOnStartup(true);
- Logging.configure(tomcat, props);
- Connectors.configure(tomcat, props);
- webappContext = Webapp.configure(tomcat, props);
+ tomcat = new Tomcat();
+ // Initialize directories
+ String basedir = tomcatBasedir().getAbsolutePath();
+ tomcat.setBaseDir(basedir);
+ tomcat.getHost().setAppBase(basedir);
+ tomcat.getHost().setAutoDeploy(false);
+ tomcat.getHost().setCreateDirs(false);
+ tomcat.getHost().setDeployOnStartup(true);
+ Logging.configure(tomcat, props);
+ Connectors.configure(tomcat, props);
+ webappContext = Webapp.configure(tomcat, props);
+ try {
tomcat.start();
- waitForWebappReady();
-
- } catch (Exception e) {
+ } catch (LifecycleException e) {
Throwables.propagate(e);
}
}
- private void waitForWebappReady() {
- while (true) {
- switch (webappContext.getState()) {
- case NEW:
- case INITIALIZING:
- case INITIALIZED:
- case STARTING_PREP:
- case STARTING:
- Uninterruptibles.sleepUninterruptibly(300L, TimeUnit.MILLISECONDS);
- break;
- case STARTED:
- // ok
- return;
- default:
- // problem, stopped or failed
- throw new IllegalStateException("YYY Webapp did not start");
- }
+ boolean isReady() {
+ switch (webappContext.getState()) {
+ case NEW:
+ case INITIALIZING:
+ case INITIALIZED:
+ case STARTING_PREP:
+ case STARTING:
+ return false;
+ case STARTED:
+ return true;
+ default:
+ // problem, stopped or failed
+ throw new IllegalStateException("Webapp did not start");
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java b/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java
index 94bc1214f0f..87ffa5c5bee 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/app/WebServer.java
@@ -41,6 +41,11 @@ public class WebServer implements MonitoredProcess {
}
@Override
+ public boolean isReady() {
+ return tomcat.isReady();
+ }
+
+ @Override
public void terminate() {
tomcat.terminate();
}