You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by "Jon Meredith (JIRA)" <ji...@apache.org> on 2019/05/09 19:57:00 UTC

[jira] [Commented] (CASSANDRA-15111) StorageService.move() throws RuntimeException when interrupted

    [ https://issues.apache.org/jira/browse/CASSANDRA-15111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16836656#comment-16836656 ] 

Jon Meredith commented on CASSANDRA-15111:
------------------------------------------

Thanks for trying out your tool on Cassandra and reporting your findings.

The {{StorageService.move}} call is invoked by {{nodetool}} when the operator wants to move the tokens owned by the node. The catch is being used to convert from checked to unchecked exceptions. Looking at StorageServerMbean, the interface has gone back and forth between checked/unchecked exceptions over time.

I can't see a way where this could fail to be handled with current usage and don't think there's an immediate need to make a change, and I know that operational systems parse the log stream generated by Cassandra so I don't want to risk breaking any tooling in a patch release that I have no way to audit.

As you say it would be possible for the interrupted/execution exception to be wrapped (although I don't think it would ever be output anywhere tracing through the default logging), and agree it would be better to do that. I've tagged this issue for 4.next.

I didn't provoke an Interrupted/ExecutionException, but did check that exceptions are making it through to logs and nodetool correctly

{panel:title=log}
ERROR [RMI TCP Connection(2)-x.x.x.x] 2019-05-09 10:29:36,965 StorageService.java:4149 - Invalid request to move(Token); This node has more than one token and cannot be moved thusly.
{panel}

{panel:title=nodetool outtput}
$ bin/nodetool  move 0
error: This node has more than one token and cannot be moved thusly.
-- StackTrace --
java.lang.UnsupportedOperationException: This node has more than one token and cannot be moved thusly.
        at org.apache.cassandra.service.StorageService.move(StorageService.java:4150)
        at org.apache.cassandra.service.StorageService.move(StorageService.java:4125)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46)
        at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237)
        at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138)
        at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
{panel}


> StorageService.move() throws RuntimeException when interrupted
> --------------------------------------------------------------
>
>                 Key: CASSANDRA-15111
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-15111
>             Project: Cassandra
>          Issue Type: Bug
>            Reporter: eBugs
>            Priority: Normal
>
> Dear Cassandra developers, we are developing a tool to detect exception-related bugs in Java. Our prototype has spotted the following {{throw}} statement whose exception class and error message indicate different error conditions.
>  
> Version: Cassandra-3.11 (commit: 123113f7b887370a248669ee0db6fdf13df0146e) 
> File: CASSANDRA-ROOT/src/java/org/apache/cassandra/service/StorageService.java
> Line: 4168
> {code:java}
> try
> {
>     relocator.stream().get();
> }
> catch (ExecutionException | InterruptedException e)
> {
>     throw new RuntimeException("Interrupted while waiting for stream/fetch ranges to finish: " + e.getMessage());
> }
> {code}
>  
> {{RuntimeException}} is usually used to represent errors in the program logic (think of one of its subclasses, {{NullPointerException}}), while the error message indicates that an interrupt has occurred. This mismatch could be a problem. For example, the callers may miss the possibility that {{StorageService.move()}} can be interrupted because it does not throw any {{InterruptedException}}. Or, the callers trying to handle other {{RuntimeException}} may accidentally (and incorrectly) handle the interrupt.
>  
> If throwing a {{RuntimeException}} is preferred, maybe it can wrap the cause exception so that the inner call stack is preserved.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org