use of com.netflix.titus.runtime.connector.common.replicator.ReplicatorEvent in project titus-control-plane by Netflix.
the class GrpcJobReplicatorEventStream method newConnection.
@Override
protected Flux<ReplicatorEvent<JobSnapshot, JobManagerEvent<?>>> newConnection() {
return Flux.<ReplicatorEvent<JobSnapshot, JobManagerEvent<?>>>create(sink -> {
CacheUpdater cacheUpdater = new CacheUpdater(jobSnapshotFactory, keepAliveEnabled, titusRuntime);
logger.info("Connecting to the job event stream (filteringCriteria={})...", filteringCriteria);
ConnectableFlux<JobManagerEvent<?>> connectableStream = client.observeJobs(filteringCriteria).publish();
Flux<JobManagerEvent<?>> augmentedStream;
if (configuration.isConnectionTimeoutEnabled()) {
augmentedStream = Flux.merge(connectableStream.take(1).timeout(Duration.ofMillis(configuration.getConnectionTimeoutMs())).ignoreElements().onErrorMap(TimeoutException.class, error -> new TimeoutException(String.format("No event received from stream in %sms", configuration.getConnectionTimeoutMs()))), connectableStream);
} else {
augmentedStream = connectableStream;
}
Disposable disposable = augmentedStream.subscribe(jobEvent -> {
long started = titusRuntime.getClock().wallTime();
try {
cacheUpdater.onEvent(jobEvent).ifPresent(sink::next);
eventProcessingLatencies.recordLevel(titusRuntime.getClock().wallTime() - started);
} catch (Exception e) {
// Throw error to force the cache reconnect.
logger.warn("Unexpected error when handling the job change notification: {}", jobEvent, e);
ExceptionExt.silent(() -> sink.error(e));
}
}, e -> ExceptionExt.silent(() -> sink.error(e)), () -> ExceptionExt.silent(sink::complete));
sink.onDispose(disposable);
connectableStream.connect();
}).doOnSubscribe(subscription -> subscriptionCounter.incrementAndGet()).doFinally(signal -> subscriptionCounter.decrementAndGet());
}
use of com.netflix.titus.runtime.connector.common.replicator.ReplicatorEvent in project titus-control-plane by Netflix.
the class GrpcJobReplicatorEventStreamTest method testCacheTaskMove.
@Test
public void testCacheTaskMove() {
Pair<Job, List<Task>> pair = jobServiceStub.createJobAndTasks(SERVICE_JOB);
Job target = jobServiceStub.createJob(SERVICE_JOB);
Task task = pair.getRight().get(0);
String sourceJobId = pair.getLeft().getId();
String targetJobId = target.getId();
List<ReplicatorEvent<JobSnapshot, JobManagerEvent<?>>> events = new ArrayList<>();
newConnectVerifier().assertNext(next -> assertThat(next.getSnapshot().getTaskMap().values()).allSatisfy(t -> assertThat(t.getStatus().getState()).isEqualTo(TaskState.Accepted))).then(() -> jobServiceStub.moveTaskToState(task, TaskState.Started)).assertNext(next -> {
JobSnapshot snapshot = next.getSnapshot();
Optional<Pair<Job<?>, Task>> taskOpt = snapshot.findTaskById(task.getId());
assertThat(taskOpt).isPresent();
assertThat(taskOpt.get().getRight().getStatus().getState()).isEqualTo(TaskState.Started);
assertThat(snapshot.getTasks(sourceJobId)).containsKey(task.getId());
}).then(() -> jobServiceStub.getJobOperations().moveServiceTask(sourceJobId, targetJobId, task.getId(), CallMetadata.newBuilder().withCallerId("Test").withCallReason("testing").build()).test().awaitTerminalEvent().assertNoErrors()).recordWith(() -> events).thenConsumeWhile(next -> {
JobManagerEvent<?> trigger = next.getTrigger();
if (!(trigger instanceof TaskUpdateEvent)) {
return true;
}
TaskUpdateEvent taskUpdateEvent = (TaskUpdateEvent) trigger;
return !taskUpdateEvent.isMovedFromAnotherJob();
}).thenCancel().verify();
assertThat(events).hasSize(3);
events.stream().map(ReplicatorEvent::getTrigger).forEach(jobManagerEvent -> {
if (jobManagerEvent instanceof JobUpdateEvent) {
JobUpdateEvent jobUpdateEvent = (JobUpdateEvent) jobManagerEvent;
String eventJobId = jobUpdateEvent.getCurrent().getId();
assertThat(eventJobId).isIn(sourceJobId, targetJobId);
} else if (jobManagerEvent instanceof TaskUpdateEvent) {
TaskUpdateEvent taskUpdateEvent = (TaskUpdateEvent) jobManagerEvent;
assertThat(taskUpdateEvent.isMovedFromAnotherJob()).isTrue();
assertThat(taskUpdateEvent.getCurrentJob().getId()).isEqualTo(targetJobId);
assertThat(taskUpdateEvent.getCurrent().getJobId()).isEqualTo(targetJobId);
assertThat(taskUpdateEvent.getCurrent().getTaskContext().get(TaskAttributes.TASK_ATTRIBUTES_MOVED_FROM_JOB)).isEqualTo(sourceJobId);
} else {
fail("Unexpected event type: %s", jobManagerEvent);
}
});
}
Aggregations