Search in sources :

Example 26 with EntityHolder

use of com.netflix.titus.common.framework.reconciler.EntityHolder in project titus-control-plane by Netflix.

the class ServiceDifferenceResolver method applyStore.

private List<ChangeAction> applyStore(ReconciliationEngine<JobManagerReconcilerEvent> engine, ServiceJobView refJobView, EntityHolder storeJob, AtomicInteger allowedNewTasks) {
    if (!storeWriteRetryInterceptor.executionLimits(storeJob)) {
        return Collections.emptyList();
    }
    List<ChangeAction> actions = new ArrayList<>();
    EntityHolder refJobHolder = refJobView.getJobHolder();
    Job<ServiceJobExt> refJob = refJobHolder.getEntity();
    if (!refJobHolder.getEntity().equals(storeJob.getEntity())) {
        actions.add(storeWriteRetryInterceptor.apply(BasicJobActions.updateJobInStore(engine, jobStore)));
    }
    boolean isJobTerminating = refJob.getStatus().getState() == JobState.KillInitiated;
    for (EntityHolder referenceTaskHolder : refJobHolder.getChildren()) {
        ServiceJobTask refTask = referenceTaskHolder.getEntity();
        Optional<EntityHolder> storeHolder = storeJob.findById(referenceTaskHolder.getId());
        ServiceJobTask storeTask = storeHolder.get().getEntity();
        boolean refAndStoreInSync = areEquivalent(storeHolder.get(), referenceTaskHolder);
        boolean shouldRetry = !isJobTerminating && refTask.getStatus().getState() == TaskState.Finished && !refTask.getStatus().getReasonCode().equals(TaskStatus.REASON_SCALED_DOWN) && allowedNewTasks.get() > 0;
        if (refAndStoreInSync) {
            TaskState currentTaskState = refTask.getStatus().getState();
            if (currentTaskState == TaskState.Finished) {
                if (isJobTerminating || isScaledDown(storeTask) || hasEnoughTasksRunning(refJobView)) {
                    actions.add(removeFinishedServiceTaskAction(jobStore, storeTask));
                } else if (shouldRetry && TaskRetryers.shouldRetryNow(referenceTaskHolder, clock)) {
                    createNewTaskAction(refJobView, Optional.of(referenceTaskHolder), Collections.emptyList(), Collections.emptyList()).ifPresent(actions::add);
                }
            }
        } else {
            Task task = referenceTaskHolder.getEntity();
            CallMetadata callMetadata = RECONCILER_CALLMETADATA.toBuilder().withCallReason("Writing runtime state changes to store").build();
            actions.add(storeWriteRetryInterceptor.apply(BasicTaskActions.writeReferenceTaskToStore(jobStore, engine, task.getId(), callMetadata, titusRuntime)));
        }
        // Both current and delayed retries are counted
        if (shouldRetry) {
            allowedNewTasks.decrementAndGet();
        }
    }
    return actions;
}
Also used : Task(com.netflix.titus.api.jobmanager.model.job.Task) ServiceJobTask(com.netflix.titus.api.jobmanager.model.job.ServiceJobTask) TitusChangeAction(com.netflix.titus.master.jobmanager.service.common.action.TitusChangeAction) ChangeAction(com.netflix.titus.common.framework.reconciler.ChangeAction) CallMetadata(com.netflix.titus.api.model.callmetadata.CallMetadata) ServiceJobExt(com.netflix.titus.api.jobmanager.model.job.ext.ServiceJobExt) ArrayList(java.util.ArrayList) EntityHolder(com.netflix.titus.common.framework.reconciler.EntityHolder) ServiceJobTask(com.netflix.titus.api.jobmanager.model.job.ServiceJobTask) TaskState(com.netflix.titus.api.jobmanager.model.job.TaskState)

Example 27 with EntityHolder

use of com.netflix.titus.common.framework.reconciler.EntityHolder in project titus-control-plane by Netflix.

the class DefaultReconciliationFrameworkTest method testMultiEngineChangeActionWithInvalidEngineId.

@Test
public void testMultiEngineChangeActionWithInvalidEngineId() {
    EntityHolder root1 = EntityHolder.newRoot("myRoot1", "myEntity1");
    framework.newEngine(root1).subscribe();
    testScheduler.triggerActions();
    Observable<Void> multiChangeObservable = framework.changeReferenceModel(// Keep anonymous class instead of lambda for readability
    new MultiEngineChangeAction() {

        @Override
        public Observable<Map<String, List<ModelActionHolder>>> apply() {
            return Observable.error(new IllegalStateException("invocation not expected"));
        }
    }, // Keep anonymous class instead of lambda for readability
    (id, modelUpdates) -> new ChangeAction() {

        @Override
        public Observable<List<ModelActionHolder>> apply() {
            return Observable.error(new IllegalStateException("invocation not expected"));
        }
    }, "myRoot1", "badRootId");
    ExtTestSubscriber<Void> multiChangeSubscriber = new ExtTestSubscriber<>();
    multiChangeObservable.subscribe(multiChangeSubscriber);
    assertThat(multiChangeSubscriber.isError()).isTrue();
    assertThat(multiChangeSubscriber.getError().getMessage()).contains("badRootId");
}
Also used : ChangeAction(com.netflix.titus.common.framework.reconciler.ChangeAction) MultiEngineChangeAction(com.netflix.titus.common.framework.reconciler.MultiEngineChangeAction) ExtTestSubscriber(com.netflix.titus.testkit.rx.ExtTestSubscriber) MultiEngineChangeAction(com.netflix.titus.common.framework.reconciler.MultiEngineChangeAction) EntityHolder(com.netflix.titus.common.framework.reconciler.EntityHolder) Observable(rx.Observable) List(java.util.List) ModelActionHolder(com.netflix.titus.common.framework.reconciler.ModelActionHolder) Test(org.junit.Test)

Example 28 with EntityHolder

use of com.netflix.titus.common.framework.reconciler.EntityHolder in project titus-control-plane by Netflix.

the class TaskTimeoutChangeActionsTest method testTimeout.

@Test
public void testTimeout() throws Exception {
    BatchJobTask launchedTask = createTaskInState(TaskState.Launched);
    EntityHolder initialRoot = rootFrom(job, launchedTask);
    EntityHolder initialChild = first(initialRoot.getChildren());
    // Initially there is no timeout associated
    TimeoutStatus timeoutStatus = TaskTimeoutChangeActions.getTimeoutStatus(initialChild, testClock);
    assertThat(timeoutStatus).isEqualTo(TimeoutStatus.NotSet);
    // Apply timeout
    List<ModelActionHolder> modelActionHolders = TaskTimeoutChangeActions.setTimeout(launchedTask.getId(), launchedTask.getStatus().getState(), DEADLINE_INTERVAL_MS, testClock).apply().toBlocking().first();
    EntityHolder rootWithTimeout = modelActionHolders.get(0).getAction().apply(initialRoot).get().getLeft();
    assertThat(TaskTimeoutChangeActions.getTimeoutStatus(first(rootWithTimeout.getChildren()), testClock)).isEqualTo(TimeoutStatus.Pending);
    // Advance time to trigger timeout
    testClock.advanceTime(DEADLINE_INTERVAL_MS, TimeUnit.MILLISECONDS);
    assertThat(TaskTimeoutChangeActions.getTimeoutStatus(first(rootWithTimeout.getChildren()), testClock)).isEqualTo(TimeoutStatus.TimedOut);
}
Also used : BatchJobTask(com.netflix.titus.api.jobmanager.model.job.BatchJobTask) EntityHolder(com.netflix.titus.common.framework.reconciler.EntityHolder) TimeoutStatus(com.netflix.titus.master.jobmanager.service.common.action.task.TaskTimeoutChangeActions.TimeoutStatus) ModelActionHolder(com.netflix.titus.common.framework.reconciler.ModelActionHolder) Test(org.junit.Test)

Example 29 with EntityHolder

use of com.netflix.titus.common.framework.reconciler.EntityHolder in project titus-control-plane by Netflix.

the class RateLimiterInterceptorTest method testRateLimiting.

@Test
public void testRateLimiting() throws Exception {
    Job<BatchJobExt> job = batchJobs(JobDescriptorGenerator.oneTaskBatchJobDescriptor()).getValue();
    // Use all tokens
    EntityHolder nextRoot = EntityHolder.newRoot("root", job);
    for (int i = 0; i < BUCKET_SIZE; i++) {
        assertThat(rateLimiterInterceptor.executionLimits(nextRoot)).isEqualTo(BUCKET_SIZE - i);
        ModelAction updateAction = executeRateLimitedAction(SampleTitusChangeActions.successfulJob());
        nextRoot = updateAction.apply(nextRoot).get().getRight();
    }
    assertThat(rateLimiterInterceptor.executionLimits(nextRoot)).isEqualTo(0);
    // Refill
    testClock.advanceTime(REFILL_INTERVAL_MS, TimeUnit.MILLISECONDS);
    assertThat(rateLimiterInterceptor.executionLimits(nextRoot)).isEqualTo(1);
}
Also used : TitusModelAction(com.netflix.titus.master.jobmanager.service.common.action.TitusModelAction) ModelAction(com.netflix.titus.common.framework.reconciler.ModelAction) BatchJobExt(com.netflix.titus.api.jobmanager.model.job.ext.BatchJobExt) EntityHolder(com.netflix.titus.common.framework.reconciler.EntityHolder) Test(org.junit.Test)

Example 30 with EntityHolder

use of com.netflix.titus.common.framework.reconciler.EntityHolder in project titus-control-plane by Netflix.

the class SingleTransaction method applyModelUpdate.

private Optional<EntityHolder> applyModelUpdate(ModelActionHolder updateAction, EntityHolder rootHolder) {
    ReconcileEventFactory<EVENT> eventFactory = engine.getEventFactory();
    try {
        return updateAction.getAction().apply(rootHolder).map(newRootAndChangedItem -> {
            EntityHolder newRoot = newRootAndChangedItem.getLeft();
            EntityHolder changedItem = newRootAndChangedItem.getRight();
            Optional<EntityHolder> previousHolder = rootHolder.findById(changedItem.getId());
            modelEventQueue.add(eventFactory.newModelUpdateEvent(engine, changeAction, updateAction, changedItem, previousHolder, transactionId));
            return newRoot;
        });
    } catch (Exception e) {
        modelEventQueue.add(eventFactory.newModelUpdateErrorEvent(engine, changeAction, updateAction, rootHolder, e, transactionId));
        logger.warn("Failed to update state of {} ({})", rootHolder.getId(), e.toString());
        throw e;
    }
}
Also used : EntityHolder(com.netflix.titus.common.framework.reconciler.EntityHolder)

Aggregations

EntityHolder (com.netflix.titus.common.framework.reconciler.EntityHolder)31 ArrayList (java.util.ArrayList)17 Task (com.netflix.titus.api.jobmanager.model.job.Task)12 ChangeAction (com.netflix.titus.common.framework.reconciler.ChangeAction)12 ModelActionHolder (com.netflix.titus.common.framework.reconciler.ModelActionHolder)12 TitusChangeAction (com.netflix.titus.master.jobmanager.service.common.action.TitusChangeAction)12 List (java.util.List)10 TaskState (com.netflix.titus.api.jobmanager.model.job.TaskState)7 TitusModelAction (com.netflix.titus.master.jobmanager.service.common.action.TitusModelAction)7 Job (com.netflix.titus.api.jobmanager.model.job.Job)6 TaskStatus (com.netflix.titus.api.jobmanager.model.job.TaskStatus)6 ServiceJobExt (com.netflix.titus.api.jobmanager.model.job.ext.ServiceJobExt)6 ReconciliationEngine (com.netflix.titus.common.framework.reconciler.ReconciliationEngine)6 JobManagerReconcilerEvent (com.netflix.titus.master.jobmanager.service.event.JobManagerReconcilerEvent)6 Test (org.junit.Test)6 JobFunctions (com.netflix.titus.api.jobmanager.model.job.JobFunctions)5 JobStore (com.netflix.titus.api.jobmanager.store.JobStore)5 CallMetadata (com.netflix.titus.api.model.callmetadata.CallMetadata)5 TitusRuntime (com.netflix.titus.common.runtime.TitusRuntime)5 Optional (java.util.Optional)5