use of org.apache.beam.runners.dataflow.worker.windmill.Windmill.StreamingGetWorkRequest in project beam by apache.
the class GrpcWindmillServerTest method testStreamingGetWork.
@Test
public void testStreamingGetWork() throws Exception {
// This fake server returns an infinite stream of identical WorkItems, obeying the request size
// limits set by the client.
serviceRegistry.addService(new CloudWindmillServiceV1Alpha1ImplBase() {
@Override
public StreamObserver<StreamingGetWorkRequest> getWorkStream(StreamObserver<StreamingGetWorkResponseChunk> responseObserver) {
return new StreamObserver<StreamingGetWorkRequest>() {
boolean sawHeader = false;
ResponseErrorInjector injector = new ResponseErrorInjector(responseObserver);
@Override
public void onNext(StreamingGetWorkRequest request) {
maybeInjectError(responseObserver);
try {
long maxItems;
if (!sawHeader) {
errorCollector.checkThat(request.getRequest(), Matchers.equalTo(GetWorkRequest.newBuilder().setClientId(10).setJobId("job").setProjectId("project").setWorkerId("worker").setMaxItems(3).setMaxBytes(10000).build()));
sawHeader = true;
maxItems = request.getRequest().getMaxItems();
} else {
maxItems = request.getRequestExtension().getMaxItems();
}
for (int item = 0; item < maxItems; item++) {
long id = ThreadLocalRandom.current().nextLong();
ByteString serializedResponse = WorkItem.newBuilder().setKey(ByteString.copyFromUtf8("somewhat_long_key")).setWorkToken(id).setShardingKey(id).build().toByteString();
// Break the WorkItem into smaller chunks to test chunking code.
for (int i = 0; i < serializedResponse.size(); i += 10) {
int end = Math.min(serializedResponse.size(), i + 10);
StreamingGetWorkResponseChunk.Builder builder = StreamingGetWorkResponseChunk.newBuilder().setStreamId(id).setSerializedWorkItem(serializedResponse.substring(i, end)).setRemainingBytesForWorkItem(serializedResponse.size() - end);
if (i == 0) {
builder.setComputationMetadata(ComputationWorkItemMetadata.newBuilder().setComputationId("comp").setDependentRealtimeInputWatermark(17000).setInputDataWatermark(18000));
}
try {
responseObserver.onNext(builder.build());
} catch (IllegalStateException e) {
// Client closed stream, we're done.
return;
}
}
}
} catch (Exception e) {
errorCollector.addError(e);
}
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onCompleted() {
injector.cancel();
responseObserver.onCompleted();
}
};
}
});
// Read the stream of WorkItems until 100 of them are received.
CountDownLatch latch = new CountDownLatch(100);
GetWorkStream stream = client.getWorkStream(GetWorkRequest.newBuilder().setClientId(10).setMaxItems(3).setMaxBytes(10000).build(), (String computation, @Nullable Instant inputDataWatermark, Instant synchronizedProcessingTime, Windmill.WorkItem workItem) -> {
latch.countDown();
assertEquals(inputDataWatermark, new Instant(18));
assertEquals(synchronizedProcessingTime, new Instant(17));
assertEquals(workItem.getKey(), ByteString.copyFromUtf8("somewhat_long_key"));
});
assertTrue(latch.await(30, TimeUnit.SECONDS));
stream.close();
assertTrue(stream.awaitTermination(30, TimeUnit.SECONDS));
}
use of org.apache.beam.runners.dataflow.worker.windmill.Windmill.StreamingGetWorkRequest in project beam by apache.
the class GrpcWindmillServerTest method testThrottleSignal.
@Test
public void testThrottleSignal() throws Exception {
// This server responds with work items until the throttleMessage limit is hit at which point it
// returns RESROUCE_EXHAUSTED errors for throttleTime msecs after which it resumes sending
// work items.
final int throttleTime = 2000;
final int throttleMessage = 15;
serviceRegistry.addService(new CloudWindmillServiceV1Alpha1ImplBase() {
long throttleStartTime = -1;
int messageCount = 0;
@Override
public StreamObserver<StreamingGetWorkRequest> getWorkStream(StreamObserver<StreamingGetWorkResponseChunk> responseObserver) {
return new StreamObserver<StreamingGetWorkRequest>() {
boolean sawHeader = false;
@Override
public void onNext(StreamingGetWorkRequest request) {
messageCount++;
// error.
if (messageCount == throttleMessage || throttleStartTime != -1) {
// If throttling has not started yet then start it.
if (throttleStartTime == -1) {
throttleStartTime = Instant.now().getMillis();
}
// throttling stop throttling.
if (throttleStartTime != -1 && ((Instant.now().getMillis() - throttleStartTime) > throttleTime)) {
throttleStartTime = -1;
}
StatusRuntimeException error = new StatusRuntimeException(Status.RESOURCE_EXHAUSTED);
responseObserver.onError(error);
return;
}
// We are not throttling this message so respond as normal.
try {
long maxItems;
if (!sawHeader) {
sawHeader = true;
maxItems = request.getRequest().getMaxItems();
} else {
maxItems = request.getRequestExtension().getMaxItems();
}
for (int item = 0; item < maxItems; item++) {
long id = ThreadLocalRandom.current().nextLong();
ByteString serializedResponse = WorkItem.newBuilder().setKey(ByteString.copyFromUtf8("somewhat_long_key")).setWorkToken(id).setShardingKey(id).build().toByteString();
StreamingGetWorkResponseChunk.Builder builder = StreamingGetWorkResponseChunk.newBuilder().setStreamId(id).setSerializedWorkItem(serializedResponse).setRemainingBytesForWorkItem(0);
try {
responseObserver.onNext(builder.build());
} catch (IllegalStateException e) {
// Client closed stream, we're done.
return;
}
}
} catch (Exception e) {
errorCollector.addError(e);
}
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onCompleted() {
responseObserver.onCompleted();
}
};
}
});
// Read the stream of WorkItems until 100 of them are received.
CountDownLatch latch = new CountDownLatch(100);
GetWorkStream stream = client.getWorkStream(GetWorkRequest.newBuilder().setClientId(10).setMaxItems(3).setMaxBytes(10000).build(), (String computation, @Nullable Instant inputDataWatermark, Instant synchronizedProcessingTime, Windmill.WorkItem workItem) -> {
latch.countDown();
});
// Wait for 100 items or 30 seconds.
assertTrue(latch.await(30, TimeUnit.SECONDS));
// Confirm that we report at least as much throttle time as our server sent errors for. We will
// actually report more due to backoff in restarting streams.
assertTrue(this.client.getAndResetThrottleTime() > throttleTime);
stream.close();
assertTrue(stream.awaitTermination(30, TimeUnit.SECONDS));
}
Aggregations