use of com.netflix.titus.master.kubernetes.client.model.PodUpdatedEvent 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));
}
use of com.netflix.titus.master.kubernetes.client.model.PodUpdatedEvent in project titus-control-plane by Netflix.
the class DefaultDirectKubeApiServerIntegrator method kubeInformerEvents.
private Flux<PodEvent> kubeInformerEvents() {
return Flux.create(sink -> {
ResourceEventHandler<V1Pod> handler = new ResourceEventHandler<V1Pod>() {
@Override
public void onAdd(V1Pod pod) {
Stopwatch stopwatch = Stopwatch.createStarted();
try {
if (!KubeUtil.isOwnedByKubeScheduler(pod)) {
return;
}
String taskId = pod.getSpec().getContainers().get(0).getName();
V1Pod old = pods.get(taskId);
pods.put(taskId, pod);
PodEvent podEvent;
if (old != null) {
podEvent = PodEvent.onUpdate(old, pod, findNode(pod));
metrics.onUpdate(pod);
} else {
podEvent = PodEvent.onAdd(pod);
metrics.onAdd(pod);
}
sink.next(podEvent);
logger.info("Pod Added: pod={}, sequenceNumber={}", formatPodEssentials(pod), podEvent.getSequenceNumber());
logger.debug("complete pod data: {}", pod);
} finally {
logger.info("Pod informer onAdd: pod={}, elapsedMs={}", pod.getMetadata().getName(), stopwatch.elapsed().toMillis());
}
}
@Override
public void onUpdate(V1Pod oldPod, V1Pod newPod) {
Stopwatch stopwatch = Stopwatch.createStarted();
try {
if (!KubeUtil.isOwnedByKubeScheduler(newPod)) {
return;
}
metrics.onUpdate(newPod);
pods.put(newPod.getSpec().getContainers().get(0).getName(), newPod);
PodUpdatedEvent podEvent = PodEvent.onUpdate(oldPod, newPod, findNode(newPod));
sink.next(podEvent);
logger.info("Pod Updated: old={}, new={}, sequenceNumber={}", formatPodEssentials(oldPod), formatPodEssentials(newPod), podEvent.getSequenceNumber());
logger.debug("Complete pod data: old={}, new={}", oldPod, newPod);
} finally {
logger.info("Pod informer onUpdate: pod={}, elapsedMs={}", newPod.getMetadata().getName(), stopwatch.elapsed().toMillis());
}
}
@Override
public void onDelete(V1Pod pod, boolean deletedFinalStateUnknown) {
Stopwatch stopwatch = Stopwatch.createStarted();
try {
if (!KubeUtil.isOwnedByKubeScheduler(pod)) {
return;
}
metrics.onDelete(pod);
pods.remove(pod.getSpec().getContainers().get(0).getName());
PodDeletedEvent podEvent = PodEvent.onDelete(pod, deletedFinalStateUnknown, findNode(pod));
sink.next(podEvent);
logger.info("Pod Deleted: {}, deletedFinalStateUnknown={}, sequenceNumber={}", formatPodEssentials(pod), deletedFinalStateUnknown, podEvent.getSequenceNumber());
logger.debug("complete pod data: {}", pod);
} finally {
logger.info("Pod informer onDelete: pod={}, elapsedMs={}", pod.getMetadata().getName(), stopwatch.elapsed().toMillis());
}
}
};
kubeApiFacade.getPodInformer().addEventHandler(handler);
// A listener cannot be removed from shared informer.
// sink.onCancel(() -> ???);
});
}
Aggregations