pauloricardomg commented on code in PR #277:
URL: https://github.com/apache/cassandra-sidecar/pull/277#discussion_r2594239495
##########
server/src/main/java/org/apache/cassandra/sidecar/lifecycle/ProcessLifecycleProvider.java:
##########
@@ -18,38 +18,232 @@
package org.apache.cassandra.sidecar.lifecycle;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
+import org.apache.cassandra.sidecar.exceptions.ConfigurationException;
+import org.jetbrains.annotations.VisibleForTesting;
/**
- * A {@link LifecycleProvider} that manages Cassandra instances as OS
processes.
- * <p>
- * This implementation is a placeholder and is not yet implemented.
+ * Manage the lifecycle of Cassandra instances running on local processes
*/
public class ProcessLifecycleProvider implements LifecycleProvider
{
+ static final String OPT_CASSANDRA_HOME = "cassandra_home";
+ static final String OPT_CASSANDRA_CONF_DIR = "cassandra_conf_dir";
+ static final String OPT_CASSANDRA_LOG_DIR = "cassandra_log_dir";
+ static final String OPT_STATE_DIR = "state_dir";
+
+ protected static final Logger LOG =
LoggerFactory.getLogger(ProcessLifecycleProvider.class);
+ public static final long CASSANDRA_PROCESS_TIMEOUT_MS =
Long.getLong("cassandra.sidecar.lifecycle.process.timeout.ms", 120_000L);
+
+ private final String lifecycleDir;
+ private final String defaultCassandraHome;
+ private final Map<String, String> defaultJvmProperties = new HashMap<>();
+ private final Map<String, String> defaultEnvVars = new HashMap<>();
+
public ProcessLifecycleProvider(Map<String, String> params)
{
- // Params unused for now
+ // Extract any JVM properties or environment variables from the params
+ for (Map.Entry<String, String> entry : params.entrySet())
+ {
+ if (entry.getKey().startsWith("cassandra."))
+ {
+ defaultJvmProperties.put(entry.getKey(), entry.getValue());
+ }
+ else if (entry.getKey().startsWith("env."))
+ {
+ defaultEnvVars.put(entry.getKey().replaceAll("env.", ""),
entry.getValue());
+ }
+ }
+ this.lifecycleDir = params.get(OPT_STATE_DIR);
+ this.defaultCassandraHome = params.get(OPT_CASSANDRA_HOME);
+ if (lifecycleDir == null || lifecycleDir.isEmpty())
+ {
+ throw new ConfigurationException("Configuration property '" +
OPT_STATE_DIR + "' must be set for ProcessLifecycleProvider");
+ }
+ if (defaultCassandraHome == null || defaultCassandraHome.isEmpty())
+ {
+ throw new ConfigurationException("Configuration property '" +
OPT_CASSANDRA_HOME + "' must be set for ProcessLifecycleProvider");
+ }
}
@Override
public void start(InstanceMetadata instance)
{
- throw new UnsupportedOperationException("Not implemented yet");
+ if (isCassandraProcessRunning(instance))
+ {
+ LOG.info("Cassandra instance {} is already running.",
instance.host());
+ return;
+ }
+ startCassandra(instance);
}
@Override
public void stop(InstanceMetadata instance)
{
- throw new UnsupportedOperationException("Not implemented yet");
-
+ if (!isCassandraProcessRunning(instance))
+ {
+ LOG.info("Cassandra instance {} is already stopped.",
instance.host());
+ return;
+ }
+ stopCassandra(instance);
}
@Override
public boolean isRunning(InstanceMetadata instance)
{
- throw new UnsupportedOperationException("Not implemented yet");
+ return isCassandraProcessRunning(instance);
+ }
+
+ private void startCassandra(InstanceMetadata instance)
+ {
+ ProcessRuntimeConfiguration runtimeConfig =
getRuntimeConfiguration(instance);
+ try
+ {
+ String stdoutLocation =
getStdoutLocation(runtimeConfig.instanceName());
+ String stderrLocation =
getStderrLocation(runtimeConfig.instanceName());
+ String pidFileLocation =
getPidFileLocation(runtimeConfig.instanceName());
+ ProcessBuilder processBuilder =
runtimeConfig.buildStartCommand(pidFileLocation,
Review Comment:
> Seems like the additional files created here - stdout/stderr - are
appended-to without rotation/cleanup and could result in disk space issues.
These files are just startup logs, not the entire Cassandra logs which are
logged to `$CASSANDRA_LOG_DIR` with proper rotation. In order to not grow the
scope of this PR while keeping the file sizes bounded I updated this patch to
overwrite the pervious startup logs instead of appending indefinitely on
c1eb0117e767d4ceef63fea8b462c81678c882fa. If needed we can add append+rotation
support later.
> Also, there is a possibility of stale PID files if the process terminates
abnormally. We would need some cleanup mechanism for such cases.
Good call. I've enhanced
`ProcessLifecycleProvider.isCassandraProcessRunning` to auto-remove the PID
file when the PID file exists but no Cassandra process is running, as well
ensure the PID file is removed on `ProcessLifecycleProvider.stop`
(0b65e3e23780126ad759ecd2bfa852e4d1630666).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]