Search in sources :

Example 1 with TaskStatus

use of com.netflix.titus.api.jobmanager.model.job.TaskStatus in project titus-control-plane by Netflix.

the class KubeNotificationProcessor method fillInMissingStates.

private static Task fillInMissingStates(PodWrapper podWrapper, Task task) {
    TaskState currentState = task.getStatus().getState();
    if (currentState != TaskState.Started && currentState != TaskState.Finished) {
        return task;
    }
    V1ContainerState containerState = podWrapper.findContainerState().orElse(null);
    if (containerState == null) {
        return task;
    }
    long startAtTimestamp;
    if (currentState == TaskState.Started) {
        if (containerState.getRunning() == null || containerState.getRunning().getStartedAt() == null) {
            return task;
        }
        startAtTimestamp = containerState.getRunning().getStartedAt().toInstant().toEpochMilli();
    } else {
        // TaskState.Finished
        if (containerState.getTerminated() == null || containerState.getTerminated().getStartedAt() == null) {
            // It must be the case where the container setup failed.
            return fillInMissingStatesForContainerSetupFailure(podWrapper, task);
        }
        startAtTimestamp = containerState.getTerminated().getStartedAt().toInstant().toEpochMilli();
    }
    TaskStatus.Builder statusTemplate = TaskStatus.newBuilder().withReasonCode(TaskStatus.REASON_STATE_MISSING).withReasonMessage("Filled in missing state update that was missed previously").withTimestamp(startAtTimestamp);
    List<TaskStatus> missingStatuses = new ArrayList<>();
    addIfMissing(task, TaskState.Launched, statusTemplate).ifPresent(missingStatuses::add);
    addIfMissing(task, TaskState.StartInitiated, statusTemplate).ifPresent(missingStatuses::add);
    addIfMissing(task, TaskState.Started, statusTemplate).ifPresent(missingStatuses::add);
    if (missingStatuses.isEmpty()) {
        return task;
    }
    List<TaskStatus> newStatusHistory = new ArrayList<>(task.getStatusHistory());
    newStatusHistory.addAll(missingStatuses);
    newStatusHistory.sort(Comparator.comparing(ExecutableStatus::getState));
    return task.toBuilder().withStatusHistory(newStatusHistory).build();
}
Also used : V1ContainerState(io.kubernetes.client.openapi.models.V1ContainerState) ArrayList(java.util.ArrayList) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus) TaskState(com.netflix.titus.api.jobmanager.model.job.TaskState)

Example 2 with TaskStatus

use of com.netflix.titus.api.jobmanager.model.job.TaskStatus in project titus-control-plane by Netflix.

the class KubeNotificationProcessor method handlePodUpdatedEvent.

private Mono<Void> handlePodUpdatedEvent(PodEvent event, Job job, Task task) {
    // This is basic sanity check. If it fails, we have a major problem with pod state.
    if (event.getPod() == null || event.getPod().getStatus() == null || event.getPod().getStatus().getPhase() == null) {
        logger.warn("Pod notification with pod without status or phase set: taskId={}, pod={}", task.getId(), event.getPod());
        metricsNoChangesApplied.increment();
        return Mono.empty();
    }
    PodWrapper podWrapper = new PodWrapper(event.getPod());
    Optional<V1Node> node;
    if (event instanceof PodUpdatedEvent) {
        node = ((PodUpdatedEvent) event).getNode();
    } else if (event instanceof PodDeletedEvent) {
        node = ((PodDeletedEvent) event).getNode();
    } else {
        node = Optional.empty();
    }
    Either<TaskStatus, String> newTaskStatusOrError = new PodToTaskMapper(podWrapper, node, task, event instanceof PodDeletedEvent, containerResultCodeResolver, titusRuntime).getNewTaskStatus();
    if (newTaskStatusOrError.hasError()) {
        logger.info(newTaskStatusOrError.getError());
        metricsNoChangesApplied.increment();
        return Mono.empty();
    }
    TaskStatus newTaskStatus = newTaskStatusOrError.getValue();
    if (TaskStatus.areEquivalent(task.getStatus(), newTaskStatus)) {
        logger.info("Pod change notification does not change task status: taskId={}, status={}, eventSequenceNumber={}", task.getId(), newTaskStatus, event.getSequenceNumber());
    } else {
        logger.info("Pod notification changes task status: taskId={}, fromStatus={}, toStatus={}, eventSequenceNumber={}", task.getId(), task.getStatus(), newTaskStatus, event.getSequenceNumber());
    }
    // against most up to date task version.
    if (!updateTaskStatus(podWrapper, newTaskStatus, node, task, true).isPresent()) {
        return Mono.empty();
    }
    return ReactorExt.toMono(v3JobOperations.updateTask(task.getId(), current -> updateTaskStatus(podWrapper, newTaskStatus, node, current, false), V3JobOperations.Trigger.Kube, "Pod status updated from kubernetes node (k8phase='" + event.getPod().getStatus().getPhase() + "', taskState=" + task.getStatus().getState() + ")", KUBE_CALL_METADATA));
}
Also used : Retry(reactor.util.retry.Retry) Task(com.netflix.titus.api.jobmanager.model.job.Task) CollectionsExt(com.netflix.titus.common.util.CollectionsExt) LoggerFactory(org.slf4j.LoggerFactory) V1PodStatus(io.kubernetes.client.openapi.models.V1PodStatus) ReactorExt(com.netflix.titus.common.util.rx.ReactorExt) KubeUtil(com.netflix.titus.master.kubernetes.KubeUtil) TITUS_NODE_DOMAIN(com.netflix.titus.runtime.kubernetes.KubeConstants.TITUS_NODE_DOMAIN) Duration(java.time.Duration) Map(java.util.Map) DirectKubeApiServerIntegrator(com.netflix.titus.master.kubernetes.client.DirectKubeApiServerIntegrator) Either(com.netflix.titus.common.util.tuple.Either) CallMetadata(com.netflix.titus.api.model.callmetadata.CallMetadata) PodEvent(com.netflix.titus.master.kubernetes.client.model.PodEvent) Job(com.netflix.titus.api.jobmanager.model.job.Job) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus) JobFunctions(com.netflix.titus.api.jobmanager.model.job.JobFunctions) TaskState(com.netflix.titus.api.jobmanager.model.job.TaskState) PodNotFoundEvent(com.netflix.titus.master.kubernetes.client.model.PodNotFoundEvent) Timer(com.netflix.spectator.api.Timer) List(java.util.List) Optional(java.util.Optional) PodWrapper(com.netflix.titus.master.kubernetes.client.model.PodWrapper) Gauge(com.netflix.spectator.api.Gauge) Disposable(reactor.core.Disposable) Stopwatch(com.google.common.base.Stopwatch) PodDeletedEvent(com.netflix.titus.master.kubernetes.client.model.PodDeletedEvent) Counter(com.netflix.spectator.api.Counter) HashMap(java.util.HashMap) MetricConstants(com.netflix.titus.master.MetricConstants) V1Node(io.kubernetes.client.openapi.models.V1Node) Singleton(javax.inject.Singleton) Scheduler(reactor.core.scheduler.Scheduler) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) Pair(com.netflix.titus.common.util.tuple.Pair) ContainerResultCodeResolver(com.netflix.titus.master.kubernetes.ContainerResultCodeResolver) Schedulers(reactor.core.scheduler.Schedulers) Evaluators.acceptNotNull(com.netflix.titus.common.util.Evaluators.acceptNotNull) KubeJobManagementReconciler(com.netflix.titus.master.kubernetes.controller.KubeJobManagementReconciler) ExecutorService(java.util.concurrent.ExecutorService) ExecutorsExt(com.netflix.titus.common.util.ExecutorsExt) Logger(org.slf4j.Logger) PodUpdatedEvent(com.netflix.titus.master.kubernetes.client.model.PodUpdatedEvent) Mono(reactor.core.publisher.Mono) Activator(com.netflix.titus.common.util.guice.annotation.Activator) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) ExecutableStatus(com.netflix.titus.api.jobmanager.model.job.ExecutableStatus) V3JobOperations(com.netflix.titus.api.jobmanager.service.V3JobOperations) TaskAttributes(com.netflix.titus.api.jobmanager.TaskAttributes) PodToTaskMapper(com.netflix.titus.master.kubernetes.PodToTaskMapper) V1ContainerState(io.kubernetes.client.openapi.models.V1ContainerState) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TitusRuntime(com.netflix.titus.common.runtime.TitusRuntime) Comparator(java.util.Comparator) Evaluators(com.netflix.titus.common.util.Evaluators) PodToTaskMapper(com.netflix.titus.master.kubernetes.PodToTaskMapper) PodDeletedEvent(com.netflix.titus.master.kubernetes.client.model.PodDeletedEvent) V1Node(io.kubernetes.client.openapi.models.V1Node) PodWrapper(com.netflix.titus.master.kubernetes.client.model.PodWrapper) PodUpdatedEvent(com.netflix.titus.master.kubernetes.client.model.PodUpdatedEvent) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus)

Example 3 with TaskStatus

use of com.netflix.titus.api.jobmanager.model.job.TaskStatus in project titus-control-plane by Netflix.

the class DifferenceResolverUtils method shouldRetry.

public static boolean shouldRetry(Job<?> job, Task task) {
    TaskStatus taskStatus = task.getStatus();
    if (taskStatus.getState() != TaskState.Finished || job.getStatus().getState() != JobState.Accepted) {
        return false;
    }
    if (hasReachedRetryLimit(job, task)) {
        return false;
    }
    if (!isBatch(job)) {
        return true;
    }
    // Batch job
    String killInitiatedReason = JobFunctions.findTaskStatus(task, TaskState.KillInitiated).map(ExecutableStatus::getReasonCode).orElse("N/A");
    if (TaskStatus.REASON_RUNTIME_LIMIT_EXCEEDED.equals(killInitiatedReason)) {
        BatchJobExt batchExt = (BatchJobExt) job.getJobDescriptor().getExtensions();
        if (!batchExt.isRetryOnRuntimeLimit()) {
            return false;
        }
    }
    return !TaskStatus.REASON_NORMAL.equals(taskStatus.getReasonCode());
}
Also used : BatchJobExt(com.netflix.titus.api.jobmanager.model.job.ext.BatchJobExt) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus)

Example 4 with TaskStatus

use of com.netflix.titus.api.jobmanager.model.job.TaskStatus in project titus-control-plane by Netflix.

the class PodToTaskMapperTest method testTaskStateAheadOfPodInRunningState.

@Test
public void testTaskStateAheadOfPodInRunningState() {
    Task task = newTask(TaskState.KillInitiated);
    V1Pod pod = newPod(andPhase("Running"), andScheduled(), andRunning(), andReason(TaskStatus.REASON_NORMAL));
    Either<TaskStatus, String> result = updateMapper(task, pod).getNewTaskStatus();
    assertErrorMessage(result, "pod state (Running) not consistent with the task state");
}
Also used : Task(com.netflix.titus.api.jobmanager.model.job.Task) V1Pod(io.kubernetes.client.openapi.models.V1Pod) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus) Test(org.junit.Test)

Example 5 with TaskStatus

use of com.netflix.titus.api.jobmanager.model.job.TaskStatus in project titus-control-plane by Netflix.

the class PodToTaskMapperTest method testUpdatesIgnoredWhenTaskFinished.

@Test
public void testUpdatesIgnoredWhenTaskFinished() {
    Task task = newTask(TaskState.Finished);
    V1Pod pod = newPod(andPhase("Pending"));
    Either<TaskStatus, String> result = updateMapper(task, pod).getNewTaskStatus();
    assertErrorMessage(result, "task already marked as finished");
}
Also used : Task(com.netflix.titus.api.jobmanager.model.job.Task) V1Pod(io.kubernetes.client.openapi.models.V1Pod) TaskStatus(com.netflix.titus.api.jobmanager.model.job.TaskStatus) Test(org.junit.Test)

Aggregations

TaskStatus (com.netflix.titus.api.jobmanager.model.job.TaskStatus)30 Task (com.netflix.titus.api.jobmanager.model.job.Task)25 V1Pod (io.kubernetes.client.openapi.models.V1Pod)20 Test (org.junit.Test)16 V1PodStatus (io.kubernetes.client.openapi.models.V1PodStatus)6 ArrayList (java.util.ArrayList)6 TaskState (com.netflix.titus.api.jobmanager.model.job.TaskState)5 Job (com.netflix.titus.api.jobmanager.model.job.Job)4 JobFunctions (com.netflix.titus.api.jobmanager.model.job.JobFunctions)4 V3JobOperations (com.netflix.titus.api.jobmanager.service.V3JobOperations)4 CallMetadata (com.netflix.titus.api.model.callmetadata.CallMetadata)4 TitusRuntime (com.netflix.titus.common.runtime.TitusRuntime)4 CollectionsExt (com.netflix.titus.common.util.CollectionsExt)4 Pair (com.netflix.titus.common.util.tuple.Pair)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Stopwatch (com.google.common.base.Stopwatch)3 Counter (com.netflix.spectator.api.Counter)3 Gauge (com.netflix.spectator.api.Gauge)3 Timer (com.netflix.spectator.api.Timer)3 TaskAttributes (com.netflix.titus.api.jobmanager.TaskAttributes)3