use of com.netflix.titus.master.jobmanager.service.event.JobModelReconcilerEvent.JobModelUpdateReconcilerEvent in project titus-control-plane by Netflix.
the class JobTransactionLoggerTest method testLogFormatting.
/**
* Sole purpose of this test is visual inspection of the generated log line.
*/
@Test
public void testLogFormatting() throws Exception {
Job previousJob = createJob();
Job currentJob = previousJob.toBuilder().withStatus(JobStatus.newBuilder().withState(JobState.Finished).build()).build();
ModelActionHolder modelActionHolder = ModelActionHolder.reference(TitusModelAction.newModelUpdate("testModelAction").job(previousJob).trigger(Trigger.API).summary("Job model update").jobUpdate(jobHolder -> jobHolder.setEntity(currentJob)));
TitusChangeAction changeAction = TitusChangeAction.newAction("testChangeAction").job(previousJob).trigger(Trigger.API).summary("Job update").callMetadata(CallMetadata.newBuilder().withCallerId("LoggerTest").withCallReason("Testing logger transaction").build()).applyModelUpdate(self -> modelActionHolder);
JobManagerReconcilerEvent jobReconcilerEvent = new JobModelUpdateReconcilerEvent(previousJob, changeAction, modelActionHolder, EntityHolder.newRoot(currentJob.getId(), currentJob), Optional.of(EntityHolder.newRoot(previousJob.getId(), previousJob)), "1");
String logLine = JobTransactionLogger.doFormat(jobReconcilerEvent);
assertThat(logLine).isNotEmpty();
logger.info("Job event: {}", logLine);
}
use of com.netflix.titus.master.jobmanager.service.event.JobModelReconcilerEvent.JobModelUpdateReconcilerEvent in project titus-control-plane by Netflix.
the class DefaultV3JobOperations method enterActiveMode.
@Activator
public void enterActiveMode() {
this.reconciliationFramework = jobReconciliationFrameworkFactory.newInstance();
// BUG: event stream breaks permanently, and cannot be retried.
// As we cannot fix the underlying issue yet, we have to be able to discover when it happens.
AtomicLong eventStreamLastError = new AtomicLong();
Clock clock = titusRuntime.getClock();
this.transactionLoggerSubscription = JobTransactionLogger.logEvents(reconciliationFramework, eventStreamLastError, clock);
PolledMeter.using(titusRuntime.getRegistry()).withName(METRIC_EVENT_STREAM_LAST_ERROR).monitorValue(eventStreamLastError, value -> value.get() <= 0 ? 0 : clock.wallTime() - value.get());
// Remove finished jobs from the reconciliation framework.
Observable<JobManagerReconcilerEvent> reconciliationEventsObservable = reconciliationFramework.events().onBackpressureBuffer(OBSERVE_JOBS_BACKPRESSURE_BUFFER_SIZE, () -> logger.warn("Overflowed the buffer size: " + OBSERVE_JOBS_BACKPRESSURE_BUFFER_SIZE), BackpressureOverflow.ON_OVERFLOW_ERROR).doOnSubscribe(() -> {
List<EntityHolder> entityHolders = reconciliationFramework.orderedView(IndexKind.StatusCreationTime);
for (EntityHolder entityHolder : entityHolders) {
handleJobCompletedEvent(entityHolder);
}
});
this.reconcilerEventSubscription = titusRuntime.persistentStream(reconciliationEventsObservable).subscribe(event -> {
if (event instanceof JobModelUpdateReconcilerEvent) {
JobModelUpdateReconcilerEvent jobUpdateEvent = (JobModelUpdateReconcilerEvent) event;
handleJobCompletedEvent(jobUpdateEvent.getChangedEntityHolder());
}
}, e -> logger.error("Event stream terminated with an error", e), () -> logger.info("Event stream completed"));
reconciliationFramework.start();
}
use of com.netflix.titus.master.jobmanager.service.event.JobModelReconcilerEvent.JobModelUpdateReconcilerEvent in project titus-control-plane by Netflix.
the class DefaultV3JobOperations method toJobManagerEvent.
private List<JobManagerEvent<?>> toJobManagerEvent(Predicate<Pair<Job<?>, List<Task>>> jobsPredicate, Predicate<Pair<Job<?>, Task>> tasksPredicate, boolean withCheckpoints, JobManagerReconcilerEvent event) {
if (event instanceof JobCheckpointReconcilerEvent) {
if (withCheckpoints) {
JobCheckpointReconcilerEvent checkpoint = (JobCheckpointReconcilerEvent) event;
return Collections.singletonList(JobManagerEvent.keepAliveEvent(checkpoint.getTimestampNano()));
}
return Collections.emptyList();
}
if (event instanceof JobNewModelReconcilerEvent) {
JobNewModelReconcilerEvent newModelEvent = (JobNewModelReconcilerEvent) event;
return toNewJobUpdateEvent(newModelEvent, jobsPredicate);
}
if (!(event instanceof JobModelUpdateReconcilerEvent)) {
return Collections.emptyList();
}
JobModelUpdateReconcilerEvent modelUpdateEvent = (JobModelUpdateReconcilerEvent) event;
if (modelUpdateEvent.getModelActionHolder().getModel() != Model.Reference) {
return Collections.emptyList();
}
if (modelUpdateEvent.getChangedEntityHolder().getEntity() instanceof Job) {
// We have to emit for this case both task archived event followed by job update event.
if (modelUpdateEvent.getChangeAction().getTrigger() == Trigger.ReconcilerServiceTaskRemoved) {
Task archivedTask = modelUpdateEvent.getChangeAction().getTask().orElse(null);
if (archivedTask != null) {
Job<?> job = modelUpdateEvent.getJob();
TaskUpdateEvent archiveEvent = TaskUpdateEvent.taskArchived(job, archivedTask, modelUpdateEvent.getCallMetadata());
List<JobManagerEvent<?>> events = new ArrayList<>();
events.add(archiveEvent);
events.addAll(toJobUpdateEvent(modelUpdateEvent, jobsPredicate));
return events;
}
}
return toJobUpdateEvent(modelUpdateEvent, jobsPredicate);
}
return toTaskUpdateEvent(modelUpdateEvent, tasksPredicate);
}
Aggregations