String resource = message.getResourceName();
String sessionId = message.getTgtSessionId();
String instanceName = manager.getInstanceName();
HelixDataAccessor accessor = manager.getHelixDataAccessor();
Builder keyBuilder = accessor.keyBuilder();
int bucketSize = message.getBucketSize();
ZNRecordBucketizer bucketizer = new ZNRecordBucketizer(bucketSize);
// Lock the helix manager so that the session id will not change when we update
// the state model state. for zk current state it is OK as we have the per-session
// current state node
synchronized (manager)
{
if (!message.getTgtSessionId().equals(manager.getSessionId()))
{
logger.warn("Session id has changed. Skip postExecutionMessage. Old session "
+ message.getExecutionSessionId() + " , new session : "
+ manager.getSessionId());
return;
}
if (taskResult.isSucess())
{
// String fromState = message.getFromState();
String toState = message.getToState();
_currentStateDelta.setState(partitionKey, toState);
if (toState.equalsIgnoreCase("DROPPED"))
{
// for "OnOfflineToDROPPED" message, we need to remove the resource key record
// from the current state of the instance because the resource key is dropped.
// In the state model it will be stayed as "OFFLINE", which is OK.
ZNRecordDelta delta =
new ZNRecordDelta(_currentStateDelta.getRecord(), MergeOperation.SUBTRACT);
// Don't subtract simple fields since they contain stateModelDefRef
delta._record.getSimpleFields().clear();
List<ZNRecordDelta> deltaList = new ArrayList<ZNRecordDelta>();
deltaList.add(delta);
_currentStateDelta.setDeltaList(deltaList);
}
else
{
// if the partition is not to be dropped, update _stateModel to the TO_STATE
_stateModel.updateState(toState);
}
}
else
{
if (exception instanceof HelixStateMismatchException)
{
// if fromState mismatch, set current state on zk to stateModel's current state
logger.warn("Force CurrentState on Zk to be stateModel's CurrentState. partitionKey: "
+ partitionKey
+ ", currentState: "
+ _stateModel.getCurrentState()
+ ", message: " + message);
_currentStateDelta.setState(partitionKey, _stateModel.getCurrentState());
}
else
{
StateTransitionError error =
new StateTransitionError(ErrorType.INTERNAL, ErrorCode.ERROR, exception);
if (exception instanceof InterruptedException)
{
if (_isTimeout)
{
error =
new StateTransitionError(ErrorType.INTERNAL,
ErrorCode.TIMEOUT,
exception);
}
else
{
// State transition interrupted but not caused by timeout. Keep the current
// state in this case
logger.error("State transition interrupted but not timeout. Not updating state. Partition : "
+ message.getPartitionName() + " MsgId : " + message.getMsgId());
return;
}
}
_stateModel.rollbackOnError(message, context, error);
_currentStateDelta.setState(partitionKey, "ERROR");
_stateModel.updateState("ERROR");
}
}
}
try
{
// Update the ZK current state of the node
PropertyKey key = keyBuilder.currentState(instanceName,
sessionId,
resource,
bucketizer.getBucketName(partitionKey));
if (!_message.getGroupMessageMode())
{