@Override public void abort() { synchronized (progress.getToken()) { transitionTo(new StateDescription(State.ABORTED, "Visitor aborted by user")); } }
transitionTo(new StateDescription(State.ABORTED, "Session explicitly destroyed before completion"));
reply.getClass().getName(); log.log(LogLevel.ERROR, msg); transitionTo(new StateDescription(State.FAILED, msg)); "' while processing reply in visitor session"; e.printStackTrace(); transitionTo(new StateDescription(State.FAILED, msg)); } catch (Throwable t) {
public void start() { synchronized (progress.getToken()) { this.startTimeNanos = clock.monotonicNanoTime(); if (progress.getIterator().isDone()) { log.log(LogLevel.DEBUG, sessionName + ": progress token indicates " + "session is done before it could even start; no-op"); return; } transitionTo(new StateDescription(State.WORKING)); taskExecutor.submitTask(new SendCreateVisitorsTask(computeBoundedMessageTimeoutMillis(0))); } }
private void handleMessageProcessingException(Reply reply, Exception e, String what) { final String errorDesc = formatProcessingException(e, what); final String fullMsg = formatIdentifyingVisitorErrorString(errorDesc); log.log(LogLevel.ERROR, fullMsg, e); int errorCode; synchronized (progress.getToken()) { if (!params.skipBucketsOnFatalErrors()) { errorCode = ErrorCode.APP_FATAL_ERROR; transitionTo(new StateDescription(State.FAILED, errorDesc)); } else { errorCode = DocumentProtocol.ERROR_UNPARSEABLE; } } reply.addError(new Error(errorCode, errorDesc)); }
private ReplyHandler createReplyHandler() { return (reply) -> { // Generally, handleReply will run in the context of the // underlying transport layer's processing thread(s), so we // schedule our own reply handling task to avoid blocking it. try { taskExecutor.submitTask(new HandleReplyTask(reply)); } catch (RejectedExecutionException e) { // We cannot reliably handle reply tasks failing to be submitted, since // the reply task performs all our internal state handling logic. As such, // we just immediately go into a failure destruction mode as soon as this // happens, in which we do not wait for any active messages to be replied // to. log.log(LogLevel.WARNING, "Visitor session '" + sessionName + "': failed to submit reply task to executor service! " + "Session cannot reliably continue; terminating it early.", e); synchronized (progress.getToken()) { transitionTo(new StateDescription(State.FAILED, "Failed to submit reply task to executor service: " + e.getMessage())); if (!done) { markSessionCompleted(); } } } }; }
private void markSessionCompleted() { // 'done' is only ever written when token mutex is held, so safe to check // outside of completionMonitor lock. assert(!done) : "Session was marked as completed more than once"; log.log(LogLevel.DEBUG, "Visitor session '" + sessionName + "' has completed"); if (params.getLocalDataHandler() != null) { params.getLocalDataHandler().onDone(); } // If skipFatalErrors is set and a fatal error did occur, fail // the session now with the first encountered error message. if (progress.getToken().containsFailedBuckets()) { transitionTo(new StateDescription(State.FAILED, progress.getToken().getFirstErrorMsg())); } // NOTE: transitioning to COMPLETED will not override a failure // state, so it's safe to always do this. transitionTo(new StateDescription(State.COMPLETED)); params.getControlHandler().onDone(state.toCompletionCode(), state.getDescription()); synchronized (completionMonitor) { done = true; completionMonitor.notifyAll(); } }
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() + "'")); } }
"' while attempting to send visitors"; log.log(LogLevel.WARNING, msg); transitionTo(new StateDescription(State.FAILED, msg));
/** * Schedule a new SendCreateVisitors task iff there are still buckets to * visit, the visiting has not failed fatally and we haven't already * scheduled such a task. */ private void scheduleSendCreateVisitorsIfApplicable(long delay, TimeUnit unit) { final long elapsedMillis = elapsedTimeMillis(); if (!isInfiniteTimeout(sessionTimeoutMillis()) && (elapsedMillis >= sessionTimeoutMillis())) { transitionTo(new StateDescription(State.TIMED_OUT, String.format("Session timeout of %d ms expired", sessionTimeoutMillis()))); if (visitingCompleted()) { markSessionCompleted(); } return; } if (!mayScheduleCreateVisitorsTask()) { return; } final long messageTimeoutMillis = computeBoundedMessageTimeoutMillis(elapsedMillis); taskExecutor.scheduleTask(new SendCreateVisitorsTask(messageTimeoutMillis), delay, unit); scheduledSendCreateVisitors = true; }
private void handleErrorReply(Reply reply) { CreateVisitorMessage msg = (CreateVisitorMessage)reply.getMessage(); // Must reset bucket progress back to what it was before sending. BucketId bucket = msg.getBuckets().get(0); BucketId subProgress = msg.getBuckets().get(1); progress.getIterator().update(bucket, subProgress); String message = getErrorMessage(reply.getError(0)); log.log(LogLevel.DEBUG, sessionName + ": received error reply for bucket " + bucket + " with message '" + message + "'"); if (isFatalError(reply)) { if (params.skipBucketsOnFatalErrors()) { markBucketProgressAsFailed(bucket, subProgress, message); } else { reportVisitorError(message); transitionTo(new StateDescription(State.FAILED, message)); return; // no additional visitors will be scheduled post-failure } } if (isErrorOfType(reply, DocumentProtocol.ERROR_WRONG_DISTRIBUTION)) { handleWrongDistributionReply((WrongDistributionReply)reply); } else { if (shouldReportError(reply)) { reportVisitorError(message); } // Wait 100ms before new visitor task is executed. Will prevent // visitors from being scheduled from caller. scheduleSendCreateVisitorsIfApplicable(100, TimeUnit.MILLISECONDS); } }