use of org.apache.helix.NotificationContext in project helix by apache.
the class HelixStateTransitionHandler method handleMessage.
@Override
public HelixTaskResult handleMessage() {
NotificationContext context = _notificationContext;
Message message = _message;
synchronized (_stateModel) {
HelixTaskResult taskResult = new HelixTaskResult();
HelixManager manager = context.getManager();
_statusUpdateUtil.logInfo(message, HelixStateTransitionHandler.class, "Message handling task begin execute", manager);
message.setExecuteStartTimeStamp(new Date().getTime());
try {
preHandleMessage();
invoke(manager, context, taskResult, message);
} catch (HelixStateMismatchException e) {
// Simply log error and return from here if State mismatch.
// The current state of the state model is intact.
taskResult.setSuccess(false);
taskResult.setMessage(e.toString());
taskResult.setException(e);
} catch (Exception e) {
String errorMessage = "Exception while executing a state transition task " + message.getPartitionName();
logger.error(errorMessage, e);
if (e.getCause() != null && e.getCause() instanceof InterruptedException) {
e = (InterruptedException) e.getCause();
}
if (e instanceof HelixRollbackException || (e.getCause() != null && e.getCause() instanceof HelixRollbackException)) {
// TODO : Support cancel to any state
logger.info("Rollback happened of state transition on resource \"" + _message.getResourceName() + "\" partition \"" + _message.getPartitionName() + "\" from \"" + _message.getFromState() + "\" to \"" + _message.getToState() + "\"");
taskResult.setCancelled(true);
} else {
_statusUpdateUtil.logError(message, HelixStateTransitionHandler.class, e, errorMessage, manager);
taskResult.setSuccess(false);
taskResult.setMessage(e.toString());
taskResult.setException(e);
taskResult.setInterrupted(e instanceof InterruptedException);
}
}
taskResult.setCompleteTime(System.currentTimeMillis());
// add task result to context for postHandling
context.add(MapKey.HELIX_TASK_RESULT.toString(), taskResult);
postHandleMessage();
return taskResult;
}
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class HelixStateTransitionHandler method invoke.
private void invoke(HelixManager manager, NotificationContext context, HelixTaskResult taskResult, Message message) throws IllegalAccessException, InvocationTargetException, InterruptedException, HelixRollbackException {
_statusUpdateUtil.logInfo(message, HelixStateTransitionHandler.class, "Message handling invoking", manager);
// by default, we invoke state transition function in state model
Method methodToInvoke = null;
String fromState = message.getFromState();
String toState = message.getToState();
methodToInvoke = _transitionMethodFinder.getMethodForTransition(_stateModel.getClass(), fromState, toState, new Class[] { Message.class, NotificationContext.class });
if (methodToInvoke != null) {
logger.info(String.format("Instance %s, partition %s received state transition from %s to %s on session %s, message id: %s", message.getTgtName(), message.getPartitionName(), message.getFromState(), message.getToState(), message.getTgtSessionId(), message.getMsgId()));
if (_cancelled) {
throw new HelixRollbackException(String.format("Instance %s, partition %s state transition from %s to %s on session %s has been cancelled, message id: %s", message.getTgtName(), message.getPartitionName(), message.getFromState(), message.getToState(), message.getTgtSessionId(), message.getMsgId()));
}
if (_cancelled) {
throw new HelixRollbackException(String.format("Instance %s, partition %s state transition from %s to %s on session %s has been cancelled", message.getTgtName(), message.getPartitionName(), message.getFromState(), message.getToState(), message.getTgtSessionId()));
}
Object result = methodToInvoke.invoke(_stateModel, new Object[] { message, context });
taskResult.setSuccess(true);
String resultStr;
if (result == null || result instanceof Void) {
resultStr = "";
} else {
resultStr = result.toString();
}
taskResult.setInfo(resultStr);
} else {
String errorMessage = "Unable to find method for transition from " + fromState + " to " + toState + " in " + _stateModel.getClass();
logger.error(errorMessage);
taskResult.setSuccess(false);
_statusUpdateUtil.logError(message, HelixStateTransitionHandler.class, errorMessage, manager);
}
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class HelixTaskExecutor method cancelTask.
@Override
public boolean cancelTask(MessageTask task) {
Message message = task.getMessage();
NotificationContext notificationContext = task.getNotificationContext();
String taskId = task.getTaskId();
synchronized (_lock) {
if (_taskMap.containsKey(taskId)) {
MessageTaskInfo taskInfo = _taskMap.get(taskId);
// cancel timeout task
if (taskInfo._timerTask != null) {
taskInfo._timerTask.cancel();
}
// cancel task
Future<HelixTaskResult> future = taskInfo.getFuture();
removeMessageFromTaskAndFutureMap(message);
_statusUpdateUtil.logInfo(message, HelixTaskExecutor.class, "Canceling task: " + taskId, notificationContext.getManager());
// return if it is interrupted.
if (future.cancel(true)) {
_statusUpdateUtil.logInfo(message, HelixTaskExecutor.class, "Canceled task: " + taskId, notificationContext.getManager());
_taskMap.remove(taskId);
return true;
} else {
_statusUpdateUtil.logInfo(message, HelixTaskExecutor.class, "fail to cancel task: " + taskId, notificationContext.getManager());
}
} else {
_statusUpdateUtil.logWarning(message, HelixTaskExecutor.class, "fail to cancel task: " + taskId + ", future not found", notificationContext.getManager());
}
}
return false;
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class CallbackHandler method handleDataChange.
@Override
public void handleDataChange(String dataPath, Object data) {
if (logger.isDebugEnabled()) {
logger.debug("Data change callback: paths changed: " + dataPath);
}
try {
updateNotificationTime(System.nanoTime());
if (dataPath != null && dataPath.startsWith(_path)) {
NotificationContext changeContext = new NotificationContext(_manager);
changeContext.setType(NotificationContext.Type.CALLBACK);
changeContext.setPathChanged(dataPath);
changeContext.setChangeType(_changeType);
enqueueTask(changeContext);
}
} catch (Exception e) {
String msg = "exception in handling data-change. path: " + dataPath + ", listener: " + _listener;
ZKExceptionHandler.getInstance().handle(msg, e);
}
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class CallbackHandler method reset.
/**
* Invoke the listener for the last time so that the listener could clean up resources
*/
public void reset() {
try {
NotificationContext changeContext = new NotificationContext(_manager);
changeContext.setType(NotificationContext.Type.FINALIZE);
changeContext.setChangeType(_changeType);
enqueueTask(changeContext);
if (_batchProcessThread != null) {
_batchProcessThread.interrupt();
}
} catch (Exception e) {
String msg = "Exception while resetting the listener:" + _listener;
ZKExceptionHandler.getInstance().handle(msg, e);
}
}
Aggregations