use of com.netflix.titus.grpc.protogen.ObserveJobsWithKeepAliveRequest in project titus-control-plane by Netflix.
the class RemoteJobManagementClientWithKeepAlive method connectObserveJobs.
/**
* Only used for unit testing to ensure internal subscriptions are not leaked.
* The <t>keepAliveCompleted</t> callback runs when the keep alive (interval) subscription is disposed
*/
@VisibleForTesting
Flux<JobChangeNotification> connectObserveJobs(Map<String, String> filteringCriteria, Runnable keepAliveCompleted) {
return Flux.create(sink -> {
AtomicReference<ClientCallStreamObserver> requestStreamRef = new AtomicReference<>();
StreamObserver<JobChangeNotification> grpcStreamObserver = new ClientResponseObserver<JobChangeNotification, JobChangeNotification>() {
@Override
public void beforeStart(ClientCallStreamObserver requestStream) {
requestStreamRef.set(requestStream);
}
@Override
public void onNext(JobChangeNotification value) {
sink.next(value);
}
@Override
public void onError(Throwable error) {
sink.error(error);
}
@Override
public void onCompleted() {
sink.complete();
}
};
StreamObserver<ObserveJobsWithKeepAliveRequest> clientStreamObserver = stub.observeJobsWithKeepAlive(grpcStreamObserver);
clientStreamObserver.onNext(ObserveJobsWithKeepAliveRequest.newBuilder().setQuery(ObserveJobsQuery.newBuilder().putAllFilteringCriteria(filteringCriteria).build()).build());
// Now emit keep alive requests periodically
Disposable keepAliveSubscription = Flux.interval(Duration.ofMillis(configuration.getKeepAliveIntervalMs())).doOnCancel(() -> ExceptionExt.doCatch(keepAliveCompleted).ifPresent(t -> logger.warn("Error running the keepAliveCompleted callback", t))).subscribe(next -> {
try {
clientStreamObserver.onNext(ObserveJobsWithKeepAliveRequest.newBuilder().setKeepAliveRequest(KeepAliveRequest.newBuilder().setRequestId(keepAliveIdGen.getAndIncrement()).setTimestamp(titusRuntime.getClock().wallTime()).build()).build());
} catch (Exception error) {
clientStreamObserver.onError(error);
}
}, sink::error, () -> sink.error(new IllegalArgumentException("Keep alive stream terminated. Closing the event stream")));
sink.onDispose(() -> {
keepAliveSubscription.dispose();
if (requestStreamRef.get() != null) {
requestStreamRef.get().cancel("ObserveJobs stream cancelled by the client", null);
}
});
});
}
use of com.netflix.titus.grpc.protogen.ObserveJobsWithKeepAliveRequest in project titus-control-plane by Netflix.
the class ObserveJobsSubscriptionTest method testObserveJobsWithKeepAliveSnapshot.
@Test
public void testObserveJobsWithKeepAliveSnapshot() {
Job<?> job1 = jobComponentStub.createJob(SERVICE_JOB_WITH_ONE_TASK);
Task task1 = jobComponentStub.createDesiredTasks(job1).get(0);
StreamObserver<ObserveJobsWithKeepAliveRequest> request = jobsSubscription.observeJobsWithKeepAlive(responseStreamObserver);
// Check that nothing is emitted until we send the query request
request.onNext(newKeepAliveRequest(1));
triggerActions(5);
assertThat(responseEvents.poll()).isNull();
// Now send the request and read the snapshot
request.onNext(QUERY_REQUEST);
request.onNext(newKeepAliveRequest(2));
assertThat(expectJobUpdateEvent().getJob().getId()).isEqualTo(job1.getId());
assertThat(expectTaskUpdateEvent().getTask().getId()).isEqualTo(task1.getId());
expectSnapshotEvent();
triggerActions(1);
jobComponentStub.emitCheckpoint();
triggerActions(1);
expectKeepAlive(2);
triggerActions(1);
// Now changes
Job<?> job2 = jobComponentStub.createJob(SERVICE_JOB_WITH_ONE_TASK);
triggerActions(1);
assertThat(expectJobUpdateEvent().getJob().getId()).isEqualTo(job2.getId());
// Now keep alive
request.onNext(newKeepAliveRequest(3));
jobComponentStub.emitCheckpoint();
triggerActions(1);
expectKeepAlive(3);
}
use of com.netflix.titus.grpc.protogen.ObserveJobsWithKeepAliveRequest in project titus-control-plane by Netflix.
the class ObserveJobsSubscriptionTest method testKeepAlive.
@Test
public void testKeepAlive() {
StreamObserver<ObserveJobsWithKeepAliveRequest> request = jobsSubscription.observeJobsWithKeepAlive(responseStreamObserver);
// Query first
request.onNext(QUERY_REQUEST);
expectSnapshotEvent();
// Now keep alive
request.onNext(newKeepAliveRequest(123));
triggerActions(5);
JobChangeNotification nextEvent = responseEvents.poll();
assertThat(nextEvent).isNull();
jobComponentStub.emitCheckpoint();
triggerActions(5);
nextEvent = responseEvents.poll();
assertThat(nextEvent).isNotNull();
assertThat(nextEvent.getNotificationCase()).isEqualTo(JobChangeNotification.NotificationCase.KEEPALIVERESPONSE);
assertThat(nextEvent.getKeepAliveResponse().getRequest().getRequestId()).isEqualTo(123);
}
use of com.netflix.titus.grpc.protogen.ObserveJobsWithKeepAliveRequest in project titus-control-plane by Netflix.
the class RemoteJobManagementClientWithKeepAliveTest method waitForClientKeepAliveRequest.
private KeepAliveRequest waitForClientKeepAliveRequest() throws InterruptedException {
Object value = receivedFromClient.poll(30, TimeUnit.SECONDS);
assertThat(value).isNotNull().isInstanceOf(ObserveJobsWithKeepAliveRequest.class);
ObserveJobsWithKeepAliveRequest event = (ObserveJobsWithKeepAliveRequest) value;
assertThat(event.getKindCase()).isEqualTo(ObserveJobsWithKeepAliveRequest.KindCase.KEEPALIVEREQUEST);
return event.getKeepAliveRequest();
}
use of com.netflix.titus.grpc.protogen.ObserveJobsWithKeepAliveRequest in project titus-control-plane by Netflix.
the class ObserveJobsSubscription method getLastObserveJobsQueryEvent.
private ObserveJobsQuery getLastObserveJobsQueryEvent() {
ObserveJobsQuery jobsQuery = null;
Pair<Long, ObserveJobsWithKeepAliveRequest> eventPair;
while ((eventPair = grpcClientEvents.poll()) != null) {
ObserveJobsWithKeepAliveRequest event = eventPair.getRight();
if (event.getKindCase() == ObserveJobsWithKeepAliveRequest.KindCase.QUERY) {
jobsQuery = event.getQuery();
}
}
return jobsQuery;
}
Aggregations