package com.hubspot.singularity;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;
import javax.annotation.Nonnull;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Iterables;
public class SingularityTaskHistoryUpdate extends SingularityTaskIdHolder implements Comparable<SingularityTaskHistoryUpdate> {
private final long timestamp;
private final ExtendedTaskState taskState;
private final Optional<String> statusMessage;
private final Optional<String> statusReason;
private final Set<SingularityTaskHistoryUpdate> previous;
public enum SimplifiedTaskState {
UNKNOWN, WAITING, RUNNING, DONE
}
public static Optional<SingularityTaskHistoryUpdate> getUpdate(final Iterable<SingularityTaskHistoryUpdate> updates, final ExtendedTaskState taskState) {
return Iterables.tryFind(updates, new Predicate<SingularityTaskHistoryUpdate>() {
@Override
public boolean apply(@Nonnull SingularityTaskHistoryUpdate input) {
return input.getTaskState() == taskState;
}
});
}
public static SimplifiedTaskState getCurrentState(Iterable<SingularityTaskHistoryUpdate> updates) {
SimplifiedTaskState state = SimplifiedTaskState.UNKNOWN;
if (updates == null) {
return state;
}
for (SingularityTaskHistoryUpdate update : updates) {
if (update.getTaskState().isDone()) {
return SimplifiedTaskState.DONE;
} else if (update.getTaskState() == ExtendedTaskState.TASK_RUNNING) {
state = SimplifiedTaskState.RUNNING;
} else if (state == SimplifiedTaskState.UNKNOWN) {
state = SimplifiedTaskState.WAITING;
}
}
return state;
}
public SingularityTaskHistoryUpdate(SingularityTaskId taskId, long timestamp, ExtendedTaskState taskState, Optional<String> statusMessage, Optional<String> statusReason) {
this(taskId, timestamp, taskState, statusMessage, statusReason, Collections.<SingularityTaskHistoryUpdate>emptySet());
}
@JsonCreator
public SingularityTaskHistoryUpdate(@JsonProperty("taskId") SingularityTaskId taskId,
@JsonProperty("timestamp") long timestamp,
@JsonProperty("taskState") ExtendedTaskState taskState,
@JsonProperty("statusMessage") Optional<String> statusMessage,
@JsonProperty("statusReason") Optional<String> statusReason,
@JsonProperty("previous") Set<SingularityTaskHistoryUpdate> previous) {
super(taskId);
this.timestamp = timestamp;
this.taskState = taskState;
this.statusMessage = statusMessage;
this.statusReason = statusReason;
this.previous = previous != null ? previous : Collections.<SingularityTaskHistoryUpdate>emptySet();
}
public SingularityTaskHistoryUpdate withPrevious(SingularityTaskHistoryUpdate previousUpdate) {
Set<SingularityTaskHistoryUpdate> newPreviousUpdates = getFlattenedPreviousUpdates(this);
newPreviousUpdates.add(previousUpdate.withoutPrevious());
newPreviousUpdates.addAll(getFlattenedPreviousUpdates(previousUpdate));
return new SingularityTaskHistoryUpdate(getTaskId(), timestamp, taskState, statusMessage, statusReason, newPreviousUpdates);
}
private Set<SingularityTaskHistoryUpdate> getFlattenedPreviousUpdates(SingularityTaskHistoryUpdate update) {
Set<SingularityTaskHistoryUpdate> previousUpdates = new HashSet<>();
for (SingularityTaskHistoryUpdate previousUpdate : update.getPrevious()) {
previousUpdates.add(previousUpdate.withoutPrevious());
previousUpdates.addAll(getFlattenedPreviousUpdates(previousUpdate));
}
return previousUpdates;
}
public SingularityTaskHistoryUpdate withoutPrevious() {
return new SingularityTaskHistoryUpdate(getTaskId(), timestamp, taskState, statusMessage, statusReason, Collections.<SingularityTaskHistoryUpdate>emptySet());
}
@Override
public int compareTo(SingularityTaskHistoryUpdate o) {
return ComparisonChain.start()
.compare(taskState.ordinal(), o.getTaskState().ordinal())
.compare(timestamp, o.getTimestamp())
.compare(o.getTaskId().getId(), getTaskId().getId())
.result();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SingularityTaskHistoryUpdate that = (SingularityTaskHistoryUpdate) o;
return timestamp == that.timestamp &&
taskState == that.taskState &&
Objects.equals(statusMessage, that.statusMessage) &&
Objects.equals(statusReason, that.statusReason);
}
@Override
public int hashCode() {
return Objects.hash(timestamp, taskState, statusMessage, statusReason);
}
public long getTimestamp() {
return timestamp;
}
public ExtendedTaskState getTaskState() {
return taskState;
}
public Optional<String> getStatusMessage() {
return statusMessage;
}
public Optional<String> getStatusReason() {
return statusReason;
}
public Set<SingularityTaskHistoryUpdate> getPrevious() {
return previous;
}
@Override public String toString() {
return "SingularityTaskHistoryUpdate[" +
"timestamp=" + timestamp +
", taskState=" + taskState +
", statusMessage=" + statusMessage +
", statusReason=" + statusReason +
", previous=" + previous +
']';
}
}