@Override public State<?, ?> handle( ClusterContext context, Message<ClusterMessage> message, MessageHolder outgoing) throws Throwable { switch (message.getMessageType()) { case configurationChanged: { ClusterMessage.ConfigurationChangeState state = message.getPayload(); if (context.getMe().equals(state.getJoin())) { context.timeouts.cancelTimeout("join"); context.joined(); outgoing.offer( message.copyHeadersTo( internal(ClusterMessage.joinResponse, context.getConfiguration()))); return entered; } else { state.apply(context); return this; } } case joiningTimeout: { context .getLogger(ClusterState.class) .info("Join timeout for " + message.getHeader(Message.CONVERSATION_ID)); // Go back to requesting configurations from potential members for (URI potentialClusterInstanceUri : context.getJoiningInstances()) { outgoing.offer(to(ClusterMessage.configurationRequest, potentialClusterInstanceUri)); } context.timeouts.setTimeout( "discovery", timeout( ClusterMessage.configurationTimeout, message, new ClusterMessage.ConfigurationTimeoutState(4))); return acquiringConfiguration; } case joinFailure: { // This causes an exception from the join() method return start; } } return this; }