public synchronized boolean updateStatus(TaskStatus taskStatus) {
		TaskStatus oldTaskStatus = taskAttemptStatusMap.get(taskStatus.getTaskAttemptID());
		// Safety check
		// already finished failed or killed task, changed can not be true
		// If TIP has failed, no need to update task attempt
		if (state.isFailed() || state.isKilled()) {
			return false;
		}

		boolean changed = oldTaskStatus == null || !oldTaskStatus.getState().equals(taskStatus.getState());
		if (changed) {
			// Task Attempt finished. This also means the TIP has finished
			if (taskStatus.getState().isFinished()) {
				this.state.setState(State.FINISH);
				execFinishedTime = System.currentTimeMillis();
				successfulTaskAttemptID = taskStatus.getTaskAttemptID();
				Log.write("Task attempt " + taskStatus.getTaskAttemptID() + " has finished");
			}
			// Task Attempt failed. This also means the TIP has partial finished
			// and should reschedule
			else if (taskStatus.getState().isFailed()) {
				this.state.setState(State.PARTIALFAILED);
				Log.warn("Task attempt " + taskStatus.getTaskAttemptID() + " has failed");
				// Exceed max retry time, task failed
				if (taskAttempNumber > RETRY_TIME) {
					this.state.setState(State.FAILED);
					execFinishedTime = System.currentTimeMillis();
					Log.warn("Task in progress " + taskInProgressID + " has failed");
				}
			}
		}
		taskAttemptStatusMap.put(taskStatus.getTaskAttemptID(), taskStatus);
		return changed;
	}