use of com.spotify.helios.common.descriptors.TaskStatusEvent in project helios by spotify.
the class JobHistoryCommand method run.
@Override
int run(final Namespace options, final HeliosClient client, final PrintStream out, final boolean json, final BufferedReader stdin) throws ExecutionException, InterruptedException {
final String jobIdString = options.getString(jobIdArg.getDest());
final Map<JobId, Job> jobs = client.jobs(jobIdString).get();
if (jobs.size() == 0) {
out.printf("Unknown job: %s%n", jobIdString);
return 1;
} else if (jobs.size() > 1) {
out.printf("Ambiguous job id: %s%n", jobIdString);
return 1;
}
final JobId jobId = getLast(jobs.keySet());
final TaskStatusEvents result = client.jobHistory(jobId).get();
if (json) {
out.println(Json.asPrettyStringUnchecked(result));
return 0;
}
final Table table = table(out);
table.row("HOST", "TIMESTAMP", "STATE", "THROTTLED", "CONTAINERID");
final List<TaskStatusEvent> events = result.getEvents();
final DateTimeFormatter format = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS");
for (final TaskStatusEvent event : events) {
final String host = checkNotNull(event.getHost());
final long timestamp = event.getTimestamp();
final TaskStatus status = checkNotNull(event.getStatus());
final State state = checkNotNull(status.getState());
String containerId = status.getContainerId();
containerId = containerId == null ? "<none>" : containerId;
table.row(host, format.print(timestamp), state, status.getThrottled(), containerId);
}
table.print();
return 0;
}
use of com.spotify.helios.common.descriptors.TaskStatusEvent in project helios by spotify.
the class TaskHistoryWriterTest method testSimpleWorkage.
@Test
public void testSimpleWorkage() throws Exception {
writer.saveHistoryItem(TASK_STATUS, TIMESTAMP);
final TaskStatusEvent historyItem = Iterables.getOnlyElement(awaitHistoryItems());
assertEquals(JOB_ID, historyItem.getStatus().getJob().getId());
}
use of com.spotify.helios.common.descriptors.TaskStatusEvent in project helios by spotify.
the class TaskHistoryWriterTest method testWriteWithZooKeeperDown.
@Test
public void testWriteWithZooKeeperDown() throws Exception {
zk.stop();
writer.saveHistoryItem(TASK_STATUS, TIMESTAMP);
zk.start();
final TaskStatusEvent historyItem = Iterables.getOnlyElement(awaitHistoryItems());
assertEquals(JOB_ID, historyItem.getStatus().getJob().getId());
}
use of com.spotify.helios.common.descriptors.TaskStatusEvent in project helios by spotify.
the class ZooKeeperMasterModel method getJobHistory.
/**
* Given a jobId and host, returns the N most recent events in its history on that host in the
* cluster.
*/
@Override
public List<TaskStatusEvent> getJobHistory(final JobId jobId, final String host) throws JobDoesNotExistException {
final Job descriptor = getJob(jobId);
if (descriptor == null) {
throw new JobDoesNotExistException(jobId);
}
final ZooKeeperClient client = provider.get("getJobHistory");
final List<String> hosts;
try {
hosts = (!isNullOrEmpty(host)) ? singletonList(host) : client.getChildren(Paths.historyJobHosts(jobId));
} catch (NoNodeException e) {
return emptyList();
} catch (KeeperException e) {
throw new RuntimeException(e);
}
final List<TaskStatusEvent> jsEvents = Lists.newArrayList();
for (final String h : hosts) {
final List<String> events;
try {
events = client.getChildren(Paths.historyJobHostEvents(jobId, h));
} catch (NoNodeException e) {
continue;
} catch (KeeperException e) {
throw new RuntimeException(e);
}
for (final String event : events) {
try {
final byte[] data = client.getData(Paths.historyJobHostEventsTimestamp(jobId, h, Long.valueOf(event)));
final TaskStatus status = Json.read(data, TaskStatus.class);
jsEvents.add(new TaskStatusEvent(status, Long.valueOf(event), h));
} catch (NoNodeException e) {
// ignore, it went away before we read it
} catch (KeeperException | IOException e) {
throw new RuntimeException(e);
}
}
}
return Ordering.from(EVENT_COMPARATOR).sortedCopy(jsEvents);
}
use of com.spotify.helios.common.descriptors.TaskStatusEvent in project helios by spotify.
the class OldJobReaper method processItem.
@Override
void processItem(final Job job) {
final JobId jobId = job.getId();
try {
final JobStatus jobStatus = masterModel.getJobStatus(jobId);
if (jobStatus == null) {
log.warn("Couldn't find job status for {} because job has already been deleted. Skipping.", jobId);
return;
}
final Map<String, Deployment> deployments = jobStatus.getDeployments();
final List<TaskStatusEvent> events = masterModel.getJobHistory(jobId);
boolean reap;
if (deployments.isEmpty()) {
if (events.isEmpty()) {
final Long created = job.getCreated();
if (created == null) {
log.info("Marked job '{}' for reaping (not deployed, no history, no creation date)", jobId);
reap = true;
} else if ((clock.now().getMillis() - created) > retentionMillis) {
log.info("Marked job '{}' for reaping (not deployed, no history, creation date " + "of {} before retention time of {} days)", jobId, DATE_FORMATTER.print(created), retentionDays);
reap = true;
} else {
log.info("NOT reaping job '{}' (not deployed, no history, creation date of {} after " + "retention time of {} days)", jobId, DATE_FORMATTER.print(created), retentionDays);
reap = false;
}
} else {
// Get the last event which is the most recent
final TaskStatusEvent event = events.get(events.size() - 1);
final String eventDate = DATE_FORMATTER.print(event.getTimestamp());
// Calculate the amount of time in milliseconds that has elapsed since the last event
final long unusedDurationMillis = clock.now().getMillis() - event.getTimestamp();
// recently should NOT BE reaped
if (unusedDurationMillis > retentionMillis && !jobsInDeploymentGroups.contains(jobId)) {
log.info("Marked job '{}' for reaping (not deployed, has history whose last event " + "on {} was before the retention time of {} days)", jobId, eventDate, retentionDays);
reap = true;
} else {
log.info("NOT reaping job '{}' (not deployed, has history whose last event " + "on {} was after the retention time of {} days)", jobId, eventDate, retentionDays);
reap = false;
}
}
} else {
// A job that's deployed should NOT BE reaped regardless of its history or creation date
reap = false;
}
if (reap) {
try {
log.info("reaping old job '{}'", job.getId());
masterModel.removeJob(jobId, job.getToken());
} catch (Exception e) {
log.warn("Failed to reap old job '{}'", jobId, e);
}
}
} catch (Exception e) {
log.warn("Failed to determine if job '{}' should be reaped", jobId, e);
}
}
Aggregations