Author: brandonwilliams Date: Fri Dec 9 18:14:14 2011 New Revision: 1212556
URL: http://svn.apache.org/viewvc?rev=1212556&view=rev Log: Add jmx method to forcibly remove endpoints. Patch by brandonwilliams reviewed by Paul Cannon for CASSANDRA-3337. Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/Gossiper.java cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/GossiperMBean.java Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/Gossiper.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/Gossiper.java?rev=1212556&r1=1212555&r2=1212556&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/Gossiper.java (original) +++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/Gossiper.java Fri Dec 9 18:14:14 2011 @@ -432,6 +432,66 @@ public class Gossiper implements IFailur } } + /** + * Do not call this method unless you know what you are doing. + * It will try extremely hard to obliterate any endpoint from the ring, + * even if it does not know about it. + * This should only ever be called by human via JMX. + * @param address + * @throws UnknownHostException + */ + public void unsafeAssassinateEndpoint(String address) throws UnknownHostException + { + InetAddress endpoint = InetAddress.getByName(address); + EndpointState epState = endpointStateMap.get(endpoint); + Token token = null; + logger.warn("Assassinating {} via gossip", endpoint); + if (epState == null) + { + epState = new EndpointState(new HeartBeatState((int)((System.currentTimeMillis() + 60000) / 1000), 9999)); + } + else + { + try + { + token = StorageService.instance.getTokenMetadata().getToken(endpoint); + } + catch (AssertionError e) + { + } + int generation = epState.getHeartBeatState().getGeneration(); + logger.info("Sleeping for " + StorageService.RING_DELAY + "ms to ensure " + endpoint + " does not change"); + try + { + Thread.sleep(StorageService.RING_DELAY); + } + catch (InterruptedException e) + { + throw new AssertionError(e); + } + // make sure it did not change + epState = endpointStateMap.get(endpoint); + if (epState.getHeartBeatState().getGeneration() != generation) + throw new RuntimeException("Endpoint " + endpoint + " generation changed while trying to remove it"); + epState.updateTimestamp(); // make sure we don't evict it too soon + epState.getHeartBeatState().forceNewerGenerationUnsafe(); + } + if (token == null) + token = StorageService.instance.getBootstrapToken(); + // do not pass go, do not collect 200 dollars, just gtfo + epState.addApplicationState(ApplicationState.STATUS, StorageService.instance.valueFactory.left(token, computeExpireTime())); + handleMajorStateChange(endpoint, epState); + try + { + Thread.sleep(intervalInMillis * 4); + } + catch (InterruptedException e) + { + throw new AssertionError(e); + } + logger.warn("Finished killing {}", endpoint); + } + public boolean isKnownEndpoint(InetAddress endpoint) { return endpointStateMap.containsKey(endpoint); Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/GossiperMBean.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/GossiperMBean.java?rev=1212556&r1=1212555&r2=1212556&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/GossiperMBean.java (original) +++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/gms/GossiperMBean.java Fri Dec 9 18:14:14 2011 @@ -28,4 +28,6 @@ public interface GossiperMBean public int getCurrentGenerationNumber(String address) throws UnknownHostException; + public void unsafeAssassinateEndpoint(String address) throws UnknownHostException; + } \ No newline at end of file