Skip to content

Commit

Permalink
Merge pull request #1442 from HubSpot/cleaning_message
Browse files Browse the repository at this point in the history
Display previous overridden cleanups
  • Loading branch information
ssalinas committed Mar 16, 2017
2 parents d03f980 + d5dc88f commit b337be3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
Expand Down Expand Up @@ -120,6 +121,10 @@ public static String durationFromMillis(final long millis) {
return DurationFormatUtils.formatDuration(Math.max(millis, 0), DURATION_FORMAT);
}

public static String formatTimestamp(final long millis) {
return DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(millis);
}

public static Thread awaitTerminationWithLatch(final CountDownLatch latch, final String threadNameSuffix, final ExecutorService service, final long millis) {
Thread t = new Thread("ExecutorServiceTerminationWaiter-" + threadNameSuffix) {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.hubspot.singularity;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;

import javax.annotation.Nonnull;
Expand All @@ -17,6 +20,7 @@ public class SingularityTaskHistoryUpdate extends SingularityTaskIdHolder implem
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
Expand Down Expand Up @@ -51,14 +55,44 @@ public static SimplifiedTaskState getCurrentState(Iterable<SingularityTaskHistor
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) {
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
Expand Down Expand Up @@ -106,12 +140,17 @@ 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 +
']';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,10 @@ public List<SingularityTaskHistoryUpdate> getTaskHistoryUpdates(SingularityTaskI
return updates;
}

public Optional<SingularityTaskHistoryUpdate> getTaskHistoryUpdate(SingularityTaskId taskId, ExtendedTaskState taskState) {
return getData(getUpdatePath(taskId, taskState), taskHistoryUpdateTranscoder);
}

public Map<SingularityTaskId, List<SingularityTaskHistoryUpdate>> getTaskHistoryUpdates(Collection<SingularityTaskId> taskIds) {
Map<String, SingularityTaskId> pathsMap = Maps.newHashMap();
for (SingularityTaskId taskId : taskIds) {
Expand Down Expand Up @@ -472,7 +476,18 @@ public SingularityCreateResult saveTaskHistoryUpdate(SingularityTaskHistoryUpdat
singularityEventListener.taskHistoryUpdateEvent(taskHistoryUpdate);

if (overwriteExisting) {
return save(getUpdatePath(taskHistoryUpdate.getTaskId(), taskHistoryUpdate.getTaskState()), taskHistoryUpdate, taskHistoryUpdateTranscoder);
Optional<SingularityTaskHistoryUpdate> maybeExisting = getTaskHistoryUpdate(taskHistoryUpdate.getTaskId(), taskHistoryUpdate.getTaskState());
LOG.info("Found existing history {}", maybeExisting);
SingularityTaskHistoryUpdate updateWithPrevious;
if (maybeExisting.isPresent()) {
updateWithPrevious = taskHistoryUpdate.withPrevious(maybeExisting.get());
LOG.info("Will save new update {}", updateWithPrevious);

} else {
updateWithPrevious = taskHistoryUpdate;
}

return save(getUpdatePath(taskHistoryUpdate.getTaskId(), taskHistoryUpdate.getTaskState()), updateWithPrevious, taskHistoryUpdateTranscoder);
} else {
return create(getUpdatePath(taskHistoryUpdate.getTaskId(), taskHistoryUpdate.getTaskState()), taskHistoryUpdate, taskHistoryUpdateTranscoder);
}
Expand Down
6 changes: 4 additions & 2 deletions SingularityUI/app/components/taskDetail/TaskHistory.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import Column from '../common/table/Column';
import classNames from 'classnames';

function TaskHistory (props) {
const previousHistories = _.flatten(_.pluck(_.filter(props.taskUpdates, (update) => {return update.previous.length > 0}), 'previous'));

return (
<Section title="History">
<UITable
emptyTableMessage="This task has no history yet"
data={props.taskUpdates.concat().reverse()}
data={_.sortBy(props.taskUpdates.concat(previousHistories), 'timestamp').reverse()}
keyGetter={(taskUpdate) => taskUpdate.timestamp}
rowChunkSize={5}
paginated={true}
paginated={false}
rowClassName={(rowData, index) => classNames({'medium-weight': index === 0})}
>
<Column
Expand Down

0 comments on commit b337be3

Please sign in to comment.