/* * @(#) GossiperStatePersister.java * Created 28.05.2013 by oleg * (C) Odnoklassniki.ru */ package org.apache.cassandra.gms; import java.io.IOException; import java.net.InetAddress; import org.apache.cassandra.db.SystemTable; import org.apache.cassandra.io.util.DataOutputBuffer; import org.apache.cassandra.utils.FBUtilities; import org.apache.log4j.Logger; /** * Persists gossiper state to system table, so it will be prepopulated on startup * * @author Oleg Anastasyev<oa@odnoklassniki.ru> * */ public class GossiperStatePersister implements IEndPointStateChangeSubscriber { private static Logger logger_ = Logger.getLogger(Gossiper.class); /* (non-Javadoc) * @see org.apache.cassandra.gms.IEndPointStateChangeSubscriber#onJoin(java.net.InetAddress, org.apache.cassandra.gms.EndPointState) */ @Override public void onJoin(InetAddress endpoint, EndPointState epState) { persistEndpointState(endpoint); } /* (non-Javadoc) * @see org.apache.cassandra.gms.IEndPointStateChangeSubscriber#onChange(java.net.InetAddress, java.lang.String, org.apache.cassandra.gms.ApplicationState) */ @Override public void onChange(InetAddress endpoint, String stateName, ApplicationState state) { persistEndpointState(endpoint); } /* (non-Javadoc) * @see org.apache.cassandra.gms.IEndPointStateChangeSubscriber#onAlive(java.net.InetAddress, org.apache.cassandra.gms.EndPointState) */ @Override public void onAlive(InetAddress endpoint, EndPointState state) { persistEndpointState(endpoint); } /* (non-Javadoc) * @see org.apache.cassandra.gms.IEndPointStateChangeSubscriber#onDead(java.net.InetAddress, org.apache.cassandra.gms.EndPointState) */ @Override public void onDead(InetAddress endpoint, EndPointState state) { persistEndpointState(endpoint); } /* (non-Javadoc) * @see org.apache.cassandra.gms.IEndPointStateChangeSubscriber#onRemove(java.net.InetAddress) */ @Override public void onRemove(InetAddress endpoint) { SystemTable.removeEndpointState(endpoint); if (logger_.isDebugEnabled()) logger_.debug("Removed endpoint "+endpoint); } private void persistEndpointState(InetAddress ep) { EndPointState endpointState = Gossiper.instance.getEndPointStateForEndPoint(ep); int generation = endpointState.getHeartBeatState().getGeneration(); int version = endpointState.getHeartBeatState().getHeartBeatVersion(); assert !ep.equals(FBUtilities.getLocalAddress()); DataOutputBuffer buffer = new DataOutputBuffer(); if (logger_.isDebugEnabled()) logger_.debug("Persisting gossip state to system table for "+endpointState.toString(ep)); try { EndPointState.serializer().serialize(endpointState, buffer); SystemTable.updateEndpointState(ep, buffer.getData(), generation, version); } catch (IOException e) { logger_.error("Cannot serialize endpointstate for "+endpointState.toString(ep)+". Will not persist.",e); } } }