2013-06-08 3 views
2

Я пишу тест единицы хранения, в котором используется блок cassandra.Получение CancellationException при выключении EmbeddedCassandraServerHelper

public class StoreTest { 

    public void before() throws Exception { 
    EmbeddedCassandraServerHelper.startEmbeddedCassandra(); 
    DataLoader dataLoader = new DataLoader("mydata", "127.0.0.1:9171"); 
    dataLoader.load(new ClassPathJsonDataSet("cassandra.json")); 
    } 

    @After 
    public void after() throws Exception { 
    EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); 
    } 

    @Test 
    public void testSomething() { 
    // test code 
    } 
} 

тест работает нормально, может подключиться к экземпляру Кассандры в памяти, и возвращать разумные результаты. Однако, когда я закрываю cassandra, я получаю следующее исключение в журналах.

17:05:48.666 [StorageServiceShutdownHook] INFO o.a.cassandra.thrift.ThriftServer - Stop listening to thrift clients 
17:05:48.667 [StorageServiceShutdownHook] INFO org.apache.cassandra.gms.Gossiper - Announcing shutdown 
17:05:48.782 [GossipTasks:1] DEBUG o.a.c.c.DebuggableThreadPoolExecutor - Task cancelled 
java.util.concurrent.CancellationException: null 
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:250) ~[na:1.7.0_21] 
    at java.util.concurrent.FutureTask.get(FutureTask.java:111) ~[na:1.7.0_21] 
    at org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor.extractThrowable(DebuggableThreadPoolExecutor.java:230) [cassandra-all-1.2.0.jar:1.2.0] 
    at org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor.logExceptionsAfterExecute(DebuggableThreadPoolExecutor.java:194) [cassandra-all-1.2.0.jar:1.2.0] 
    at org.apache.cassandra.concurrent.DebuggableScheduledThreadPoolExecutor.afterExecute(DebuggableScheduledThreadPoolExecutor.java:46) [cassandra-all-1.2.0.jar:1.2.0] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153) [na:1.7.0_21] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_21] 
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21] 
17:05:49.667 [StorageServiceShutdownHook] INFO o.a.cassandra.net.MessagingService - Waiting for messaging service to quiesce 
17:05:49.668 [ACCEPT-/27.0.0.1] INFO o.a.cassandra.net.MessagingService - MessagingService shutting down server thread. 

Где это происходит и как я могу предотвратить его?

ответ

0

Похоже, что существует проблема с методом остановки. Я предполагаю, что рабочий поток для части системы, которая все еще отключается, прерывается до того, как он будет завершен. Код latest EmbeddedCassandraServerHelper обесценивает метод stopEmbeddedCassandra с комментарием о том, что он не работает полностью.

Мы вставляем кассандру в наши модульные тесты, используя наш собственный код. Мы не используем метод activate(), как класс EmbeddedCassandraServerHelper, но вместо этого используем методы init() и start() CassandraDaemon. Тогда метод stop() работает. Cassandra не встраивается отлично, как ожидается, будет выполняться под jsvc.

Если у вас нет каких-либо проблем помимо раздражающего сообщения журнала, я бы просто настроить ведение журнала для подавления этого класса. В противном случае попробуйте заменить вызов метода active() в EmbeddedCassandraServerHelper с помощью методов init()/start().

0

Проблема заключается в методе DebuggableThreadPoolExecutor.extractThrowable. Исходный код:

public static Throwable extractThrowable(Runnable runnable) 
{ 
    // Check for exceptions wrapped by FutureTask. We do this by calling get(), which will 
    // cause it to throw any saved exception. 
    // 
    // Complicating things, calling get() on a ScheduledFutureTask will block until the task 
    // is cancelled. Hence, the extra isDone check beforehand. 
    if ((runnable instanceof Future<?>) && ((Future<?>) runnable).isDone()) 
    { 
     try 
     { 
      ((Future<?>) runnable).get(); 
     } 
     catch (InterruptedException e) 
     { 
      throw new AssertionError(e); 
     } 
     catch (CancellationException e) 
     { 
      logger.debug("Task cancelled", e); 
     } 
     catch (ExecutionException e) 
     { 
      return e.getCause(); 
     } 
    } 

    return null; 
} 

Как видно, он регистрирует отмену задачи с предупреждением об отладке. То, что я сделал, это изменение линии logger.debug("Task cancelled", e); на logger.debug("Task cancelled (see DebuggableThreadPoolExecutor.extractThrowable)");. Таким образом, событие регистрируется, но не загрязняет журнал со следами стека, которые привлекают внимание.

Смежные вопросы