ErrorType type = ErrorType.INTERNAL;
ErrorCode code = ErrorCode.ERROR;
long start = System.currentTimeMillis();
logger.info("msg:" + _message.getMsgId() + " handling task begin, at: " + start);
HelixDataAccessor accessor = _manager.getHelixDataAccessor();
_statusUpdateUtil.logInfo(_message,
HelixTask.class,
"Message handling task begin execute",
accessor);
_message.setExecuteStartTimeStamp(new Date().getTime());
// Handle the message
try
{
taskResult = _handler.handleMessage();
exception = taskResult.getException();
}
catch (InterruptedException e)
{
_statusUpdateUtil.logError(_message,
HelixTask.class,
e,
"State transition interrupted, timeout:" + _isTimeout,
accessor);
logger.info("Message " + _message.getMsgId() + " is interrupted");
taskResult.setInterrupted(true);
taskResult.setException(e);
exception = e;
}
catch (Exception e)
{
String errorMessage =
"Exception while executing a message. " + e + " msgId: " + _message.getMsgId()
+ " type: " + _message.getMsgType();
logger.error(errorMessage, e);
_statusUpdateUtil.logError(_message, HelixTask.class, e, errorMessage, accessor);
taskResult.setSuccess(false);
taskResult.setException(e);
taskResult.setMessage(e.getMessage());
exception = e;
}
// Cancel the timer since the handling is done
// it is fine if the TimerTask for canceling is called already
if (timer != null)
{
timer.cancel();
}
if (taskResult.isSucess())
{
_statusUpdateUtil.logInfo(_message,
_handler.getClass(),
"Message handling task completed successfully",
accessor);
logger.info("Message " + _message.getMsgId() + " completed.");
}
else if (taskResult.isInterrupted())
{
logger.info("Message " + _message.getMsgId() + " is interrupted");
code = _isTimeout ? ErrorCode.TIMEOUT : ErrorCode.CANCEL;
if (_isTimeout)
{
int retryCount = _message.getRetryCount();
logger.info("Message timeout, retry count: " + retryCount + " MSGID:"
+ _message.getMsgId());
_statusUpdateUtil.logInfo(_message,
_handler.getClass(),
"Message handling task timeout, retryCount:"
+ retryCount,
accessor);
// Notify the handler that timeout happens, and the number of retries left
// In case timeout happens (time out and also interrupted)
// we should retry the execution of the message by re-schedule it in
if (retryCount > 0)
{
_message.setRetryCount(retryCount - 1);
_executor.scheduleTask(_message, _handler, _notificationContext);
return taskResult;
}
}
}
else
// logging for errors
{
String errorMsg =
"Message execution failed. msgId: " + _message.getMsgId()
+ taskResult.getMessage();
if (exception != null)
{
errorMsg += exception;
}
logger.error(errorMsg, exception);
_statusUpdateUtil.logError(_message, _handler.getClass(), errorMsg, accessor);
}
// Post-processing for the finished task
try
{
if (!_message.getGroupMessageMode())
{
removeMessageFromZk(accessor, _message);
reportMessageStat(_manager, _message, taskResult);
sendReply(accessor, _message, taskResult);
}
else
{
GroupMessageInfo info = _executor._groupMsgHandler.onCompleteSubMessage(_message);
if (info != null)
{
// TODO: changed to async update
// group update current state
Map<PropertyKey, CurrentState> curStateMap = info.merge();
for (PropertyKey key : curStateMap.keySet())
{
accessor.updateProperty(key, curStateMap.get(key));
}
// remove group message
removeMessageFromZk(accessor, _message);
reportMessageStat(_manager, _message, taskResult);