@Override protected DocumentReply doDecode(DocumentDeserializer buf) { WrongDistributionReply reply = new WrongDistributionReply(); reply.setSystemState(decodeString(buf)); return reply; }
private void markReplyAsImmediateRetryIfNewStateObserved(WrongDistributionReply reply, MessageContext context, ClusterState newState) { if (context.usedState != null && newState.getVersion() <= context.usedState.getVersion()) { if (reply.getRetryDelay() <= 0.0) { reply.setRetryDelay(-1); } } else { if (reply.getRetryDelay() <= 0.0) { reply.setRetryDelay(0); } } }
private static Optional<ClusterState> clusterStateFromReply(final WrongDistributionReply reply) { try { return Optional.of(new ClusterState(reply.getSystemState())); } catch (Exception e) { reply.getTrace().trace(1, "Error when parsing system state string " + reply.getSystemState()); return Optional.empty(); } }
@Override protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { WrongDistributionReply reply = (WrongDistributionReply)obj; encodeString(reply.getSystemState(), buf); return true; } }
private void traceReplyFromRandomDistributor(WrongDistributionReply reply, ClusterState newState) { if (!reply.getTrace().shouldTrace(1)) { return; } if (cachedClusterState == null) { reply.getTrace().trace(1, "Message sent to * with no previous state, received version " + newState.getVersion()); } else if (newState.getVersion() == cachedClusterState.getVersion()) { reply.getTrace().trace(1, "Message sent to * found that cluster state version " + newState.getVersion() + " was correct."); } else if (newState.getVersion() > cachedClusterState.getVersion()) { reply.getTrace().trace(1, "Message sent to * updated cluster state to version " + newState.getVersion()); } else { reply.getTrace().trace(1, "Message sent to * retrieved older cluster state version " + newState.getVersion()); } }
Reply reply = new WrongDistributionReply(cachedClusterState.toString(true)); reply.addError(new Error(DocumentProtocol.ERROR_WRONG_DISTRIBUTION, "Too few distribution bits used for given cluster state"));
private void handleWrongDistributionReply(WrongDistributionReply reply) { try { ClusterState newState = new ClusterState(reply.getSystemState()); int stateBits = newState.getDistributionBitCount(); if (stateBits != progress.getIterator().getDistributionBitCount()) { log.log(LogLevel.DEBUG, "System state changed; now at " + stateBits + " distribution bits"); // Update the internal state of the visitor iterator. If we're increasing // the number of distribution bits, this may lead to splitting of pending // buckets. If we're decreasing, it may lead to merging of pending buckets // and potential loss of sub-bucket progress. In either way, the iterator // will not let any new buckets out before all active buckets have been // updated. progress.getIterator().setDistributionBitCount(stateBits); } } catch (Exception e) { log.log(LogLevel.ERROR, "Failed to parse new system state string: " + reply.getSystemState()); transitionTo(new StateDescription(State.FAILED, "Failed to parse cluster state '" + reply.getSystemState() + "'")); } }
private void traceReplyFromSpecificDistributor(WrongDistributionReply reply, MessageContext context, ClusterState newState) { if (context.usedState == null) { String msg = "Used state must be set as distributor is calculated. Bug."; reply.getTrace().trace(1, msg); log.log(LogLevel.ERROR, msg); } else if (newState.getVersion() == context.usedState.getVersion()) { String msg = "Message sent to distributor " + context.calculatedDistributor + " retrieved cluster state version " + newState.getVersion() + " which was the state we used to calculate distributor as target last time."; reply.getTrace().trace(1, msg); // Client load can be rejected towards distributors even with a matching cluster state version. // This usually happens during a node fail-over transition, where the target distributor will // reject an operation bound to a particular bucket if it does not own the bucket in _both_ // the current and the next (transition target) state. Since it can happen during normal operation // and will happen per client operation, we keep this as debug level to prevent spamming the logs. log.log(LogLevel.DEBUG, msg); } else if (newState.getVersion() > context.usedState.getVersion()) { if (reply.getTrace().shouldTrace(1)) { reply.getTrace().trace(1, "Message sent to distributor " + context.calculatedDistributor + " updated cluster state from version " + context.usedState.getVersion() + " to " + newState.getVersion()); } } else { if (reply.getTrace().shouldTrace(1)) { reply.getTrace().trace(1, "Message sent to distributor " + context.calculatedDistributor + " returned older cluster state version " + newState.getVersion()); } } }