1 package com.thinkaurelius.titan.diskstorage.cassandra.utils;
3 import java.lang.Thread.UncaughtExceptionHandler;
5 import org.apache.cassandra.config.Schema;
6 import org.apache.cassandra.db.commitlog.CommitLog;
7 import org.apache.cassandra.net.MessagingService;
8 import org.apache.cassandra.service.CassandraDaemon;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
13 * This class starts a Thrift CassandraDaemon inside the current JVM. This class
14 * supports testing and shouldn't be used in production.
16 * This class starts Cassandra on the first invocation of
17 * {@link CassandraDaemonWrapper#start(String)} in the life of the JVM.
18 * Invocations after the first have no effect except that they may log a
21 * When the thread that first called {@code #start(String)} dies, a daemon
22 * thread returns from {@link Thread#join()} and kills all embedded Cassandra
25 * This class once supported consecutive, idempotent calls to start(String) so
26 * long as the argument was the same in each invocation. It also once used
27 * refcounting to kill Cassandra's non-daemon threads once stop() was called as
28 * many times as start(). Some of Cassandra's background threads and statics
29 * can't be easily reset to allow a restart inside the same JVM, so this was
30 * intended as a one-use thing. However, this interacts poorly with the new
31 * KCVConfiguration system in titan-core. When KCVConfiguration is in use, core
32 * starts and stops each backend at least twice in the course of opening a
33 * single database instance. So the old refcounting and killing approach is out.
35 * @author Dan LaRocque <dalaro@hopcount.org>
37 public class CassandraDaemonWrapper {
39 private static final Logger log =
40 LoggerFactory.getLogger(CassandraDaemonWrapper.class);
42 private static String activeConfig;
44 private static boolean started;
46 public static synchronized void start(String config) {
49 if (null != config && !config.equals(activeConfig)) {
50 log.warn("Can't start in-process Cassandra instance " +
51 "with yaml path {} because an instance was " +
52 "previously started with yaml path {}",
53 config, activeConfig);
61 log.debug("Current working directory: {}", System.getProperty("user.dir"));
63 System.setProperty("cassandra.config", config);
64 // Prevent Cassandra from closing stdout/stderr streams
65 System.setProperty("cassandra-foreground", "yes");
66 // Prevent Cassandra from overwriting Log4J configuration
67 System.setProperty("log4j.defaultInitOverride", "false");
69 log.info("Starting cassandra with {}", config);
72 * This main method doesn't block for any substantial length of time. It
73 * creates and starts threads and returns in relatively short order.
75 CassandraDaemon.main(new String[0]);
77 activeConfig = config;
80 public static synchronized boolean isStarted() {
84 public static void stop() {