use of com.netflix.titus.api.jobmanager.store.JobStore in project titus-control-plane by Netflix.
the class CassandraJobStoreTest method testDeleteJob.
@Test
public void testDeleteJob() {
JobStore store = getJobStore();
Job<BatchJobExt> job = createBatchJobObject();
store.init().await();
store.storeJob(job).await();
Pair<List<Job<?>>, Integer> jobsAndErrors = store.retrieveJobs().toBlocking().first();
checkRetrievedJob(job, jobsAndErrors.getLeft().get(0));
store.deleteJob(job).await();
jobsAndErrors = store.retrieveJobs().toBlocking().first();
assertThat(jobsAndErrors.getLeft()).isEmpty();
}
use of com.netflix.titus.api.jobmanager.store.JobStore in project titus-control-plane by Netflix.
the class TestStoreLoadCommand method execute.
@Override
public void execute(CommandContext commandContext) {
CommandLine commandLine = commandContext.getCommandLine();
String keyspace = commandContext.getTargetKeySpace();
Integer jobs = Integer.valueOf(commandLine.getOptionValue("jobs"));
Integer tasks = Integer.valueOf(commandLine.getOptionValue("tasks"));
Integer concurrency = Integer.valueOf(commandLine.getOptionValue("concurrency"));
Integer iterations = Integer.valueOf(commandLine.getOptionValue("iterations"));
Session session = commandContext.getTargetSession();
boolean keyspaceExists = session.getCluster().getMetadata().getKeyspace(keyspace) != null;
if (!keyspaceExists) {
throw new IllegalStateException("Keyspace: " + keyspace + " does not exist. You must create it first.");
}
session.execute("USE " + keyspace);
JobStore titusStore = new CassandraJobStore(CONFIGURATION, session, TitusRuntimes.internal());
// Create jobs and tasks
long jobStartTime = System.currentTimeMillis();
List<Observable<Void>> createJobAndTasksObservables = new ArrayList<>();
for (int i = 0; i < jobs; i++) {
createJobAndTasksObservables.add(createJobAndTasksObservable(tasks, titusStore));
}
Observable.merge(createJobAndTasksObservables, concurrency).toBlocking().subscribe(none -> {
}, e -> logger.error("Error creating jobs: ", e), () -> {
logger.info("Created {} jobs with {} tasks in {}[ms]", jobs, tasks, System.currentTimeMillis() - jobStartTime);
});
// try loading jobs and tasks for i iterations
long loadTotalTime = 0L;
for (int i = 0; i < iterations; i++) {
long loadStartTime = System.currentTimeMillis();
List<Pair<Job, List<Task>>> pairs = new ArrayList<>();
titusStore.init().andThen(titusStore.retrieveJobs().flatMap(retrievedJobsAndErrors -> {
List<Job<?>> retrievedJobs = retrievedJobsAndErrors.getLeft();
List<Observable<Pair<Job, List<Task>>>> retrieveTasksObservables = new ArrayList<>();
for (Job job : retrievedJobs) {
Observable<Pair<Job, List<Task>>> retrieveTasksObservable = titusStore.retrieveTasksForJob(job.getId()).map(taskList -> new Pair<>(job, taskList.getLeft()));
retrieveTasksObservables.add(retrieveTasksObservable);
}
return Observable.merge(retrieveTasksObservables, MAX_RETRIEVE_TASK_CONCURRENCY);
})).map(p -> {
pairs.add(p);
return null;
}).toBlocking().subscribe(none -> {
}, e -> logger.error("Failed to load jobs from cassandra with error: ", e), () -> {
});
long loadTime = System.currentTimeMillis() - loadStartTime;
logger.info("Loaded {} jobs from cassandra in {}[ms]", pairs.size(), loadTime);
loadTotalTime += loadTime;
}
logger.info("Average load time: {}[ms]", loadTotalTime / iterations);
}
use of com.netflix.titus.api.jobmanager.store.JobStore in project titus-control-plane by Netflix.
the class BatchDifferenceResolver method createNewTaskAction.
private Optional<TitusChangeAction> createNewTaskAction(BatchJobView refJobView, int taskIndex, Optional<EntityHolder> previousTask, List<String> unassignedIpAllocations, List<String> ebsVolumeIds) {
// Safety check
long numberOfNotFinishedTasks = refJobView.getJobHolder().getChildren().stream().filter(holder -> TaskState.isRunning(((Task) holder.getEntity()).getStatus().getState())).count();
if (numberOfNotFinishedTasks >= refJobView.getRequiredSize()) {
titusRuntime.getCodeInvariants().inconsistent("Batch job reconciler attempts to create too many tasks: jobId=%s, requiredSize=%s, current=%s", refJobView.getJob().getId(), refJobView.getRequiredSize(), numberOfNotFinishedTasks);
return Optional.empty();
}
Map<String, String> taskContext = getTaskContext(previousTask, unassignedIpAllocations, ebsVolumeIds);
JobDescriptor jobDescriptor = refJobView.getJob().getJobDescriptor();
ApplicationSLA capacityGroupDescriptor = JobManagerUtil.getCapacityGroupDescriptor(jobDescriptor, capacityGroupService);
String resourcePool = capacityGroupDescriptor.getResourcePool();
taskContext = CollectionsExt.copyAndAdd(taskContext, ImmutableMap.of(TaskAttributes.TASK_ATTRIBUTES_RESOURCE_POOL, resourcePool, TaskAttributes.TASK_ATTRIBUTES_TIER, capacityGroupDescriptor.getTier().name()));
TitusChangeAction storeAction = storeWriteRetryInterceptor.apply(createOrReplaceTaskAction(runtime, jobStore, refJobView.getJobHolder(), taskIndex, versionSupplier, clock, taskContext));
return Optional.of(storeAction);
}
use of com.netflix.titus.api.jobmanager.store.JobStore in project titus-control-plane by Netflix.
the class BasicTaskActions method writeReferenceTaskToStore.
/**
* Write updated task record to a store. If a task is completed, remove it from the scheduling service.
* This command calls {@link JobStore#updateTask(Task)}, which assumes that the task record was created already.
*/
public static TitusChangeAction writeReferenceTaskToStore(JobStore titusStore, ReconciliationEngine<JobManagerReconcilerEvent> engine, String taskId, CallMetadata callMetadata, TitusRuntime titusRuntime) {
return TitusChangeAction.newAction("writeReferenceTaskToStore").trigger(V3JobOperations.Trigger.Reconciler).id(taskId).summary("Persisting task to the store").callMetadata(callMetadata).changeWithModelUpdate(self -> {
Optional<EntityHolder> taskHolder = engine.getReferenceView().findById(taskId);
if (!taskHolder.isPresent()) {
// Should never happen
titusRuntime.getCodeInvariants().inconsistent("Reference task with id %s not found.", taskId);
return Observable.empty();
}
Task referenceTask = taskHolder.get().getEntity();
return titusStore.updateTask(referenceTask).andThen(Observable.fromCallable(() -> {
TitusModelAction modelUpdateAction = TitusModelAction.newModelUpdate(self).taskUpdate(storeRoot -> {
EntityHolder storedHolder = EntityHolder.newRoot(referenceTask.getId(), referenceTask);
return Pair.of(storeRoot.addChild(storedHolder), storedHolder);
});
return ModelActionHolder.store(modelUpdateAction);
}));
});
}
use of com.netflix.titus.api.jobmanager.store.JobStore in project titus-control-plane by Netflix.
the class KillInitiatedActions method reconcilerInitiatedAllTasksKillInitiated.
/**
* For all active tasks, send terminate command to the compute provider, and change their state to {@link TaskState#KillInitiated}.
* This method is used for internal state reconciliation.
*/
public static List<ChangeAction> reconcilerInitiatedAllTasksKillInitiated(ReconciliationEngine<JobManagerReconcilerEvent> engine, JobServiceRuntime runtime, JobStore jobStore, String reasonCode, String reason, int concurrencyLimit, VersionSupplier versionSupplier, TitusRuntime titusRuntime) {
List<ChangeAction> result = new ArrayList<>();
EntityHolder runningView = engine.getRunningView();
Set<String> runningTaskIds = new HashSet<>();
runningView.getChildren().forEach(taskHolder -> runningTaskIds.add(taskHolder.<Task>getEntity().getId()));
// Immediately finish Accepted tasks, which are not yet in the running model.
for (EntityHolder entityHolder : engine.getReferenceView().getChildren()) {
if (result.size() >= concurrencyLimit) {
return result;
}
Task task = entityHolder.getEntity();
TaskState state = task.getStatus().getState();
if (state == TaskState.Accepted && !runningTaskIds.contains(task.getId())) {
result.add(BasicTaskActions.updateTaskAndWriteItToStore(task.getId(), engine, taskRef -> JobFunctions.changeTaskStatus(taskRef, TaskState.Finished, reasonCode, reason, titusRuntime.getClock()), jobStore, V3JobOperations.Trigger.Reconciler, reason, versionSupplier, titusRuntime, JobManagerConstants.RECONCILER_CALLMETADATA.toBuilder().withCallReason(reason).build()));
}
}
// Move running tasks to KillInitiated state
for (EntityHolder taskHolder : runningView.getChildren()) {
if (result.size() >= concurrencyLimit) {
return result;
}
Task task = taskHolder.getEntity();
TaskState state = task.getStatus().getState();
if (state != TaskState.KillInitiated && state != TaskState.Finished) {
result.add(reconcilerInitiatedTaskKillInitiated(engine, task, runtime, jobStore, versionSupplier, reasonCode, reason, titusRuntime));
}
}
return result;
}
Aggregations