use of com.linkedin.r2.message.stream.entitystream.Observer in project rest.li by linkedin.
the class BackupRequestsClient method streamRequest.
@Override
public void streamRequest(StreamRequest request, RequestContext requestContext, Callback<StreamResponse> callback) {
// Currently only support backup requests with IS_FULL_REQUEST.
if (!isFullRequest(requestContext)) {
_d2Client.streamRequest(request, requestContext, callback);
return;
}
if (!isBuffered(requestContext)) {
final FullEntityObserver observer = new FullEntityObserver(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
LOG.warn("Failed to record request's entity for retrying backup request.");
}
@Override
public void onSuccess(ByteString result) {
requestContext.putLocalAttr(R2Constants.BACKUP_REQUEST_BUFFERED_BODY, result);
}
});
request.getEntityStream().addObserver(observer);
}
if (_isD2Async) {
requestAsync(request, requestContext, _d2Client::streamRequest, callback);
return;
}
_d2Client.streamRequest(request, requestContext, decorateCallbackSync(request, requestContext, _d2Client::streamRequest, callback));
}
use of com.linkedin.r2.message.stream.entitystream.Observer in project rest.li by linkedin.
the class TestEntityStream method testRaceBetweenDoneAndCancel.
private void testRaceBetweenDoneAndCancel(ExecutorService executor) throws Exception {
final CountDownLatch startLatch = new CountDownLatch(1);
final CountDownLatch finishLatch = new CountDownLatch(2);
final CountDownLatch prepareLatch = new CountDownLatch(2);
final TestWriter writer = new TestWriter();
TestObserver observer = new TestObserver();
final ControlReader reader = new ControlReader();
EntityStream es = EntityStreams.newEntityStream(writer);
es.addObserver(observer);
es.setReader(reader);
reader.read(1000);
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
while (writer.remaining() > 100) {
writer.write();
}
prepareLatch.countDown();
startLatch.await();
writer.done();
finishLatch.countDown();
return null;
}
});
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
prepareLatch.countDown();
startLatch.await();
reader.cancel();
finishLatch.countDown();
return null;
}
});
prepareLatch.await();
startLatch.countDown();
Assert.assertTrue(finishLatch.await(1000, TimeUnit.MILLISECONDS));
// in any case, reader shouldn't fail
Assert.assertEquals(reader.errorTimes(), 0);
// if done wins the race
if (reader.doneTimes() > 0) {
Assert.assertEquals(reader.doneTimes(), 1);
Assert.assertEquals(observer.doneTimes(), 1);
Assert.assertEquals(observer.errorTimes(), 0);
Assert.assertEquals(writer.abortedTimes(), 0);
} else // if cancel wins the race
{
Assert.assertEquals(observer.doneTimes(), 0);
Assert.assertEquals(observer.errorTimes(), 1);
Assert.assertEquals(writer.abortedTimes(), 1);
}
}
use of com.linkedin.r2.message.stream.entitystream.Observer in project rest.li by linkedin.
the class TestEntityStream method testObserverThrowRuntimeException.
/**
* This test will check the correct behavior in case of a Runtime Exception for the observer.
* Note the Runtime Exception is not the only unchecked exception, and we have to consider also Error
* which is the other unchecked throwable
*/
@Test
public void testObserverThrowRuntimeException() {
Observer observer = new TestObserver() {
@Override
public void onDone() {
throw new RuntimeException("broken observer throws");
}
@Override
public void onDataAvailable(ByteString data) {
throw new RuntimeException("broken observer throws");
}
@Override
public void onError(Throwable ex) {
throw new RuntimeException("broken observer throws");
}
};
Exception ex = new RuntimeException("writer has problem");
testObserverThrow(observer, ex);
}
use of com.linkedin.r2.message.stream.entitystream.Observer in project rest.li by linkedin.
the class TestEntityStream method testObserverThrow.
public void testObserverThrow(Observer observer, Throwable writeError) {
TestWriter writer = new TestWriter();
ControlReader reader = new ControlReader();
EntityStream es = EntityStreams.newEntityStream(writer);
es.addObserver(observer);
es.setReader(reader);
reader.read(1);
writer.write();
writer.done();
writer.error(writeError);
Assert.assertEquals(writer.abortedTimes(), 0);
Assert.assertEquals(reader.getChunkCount(), 1);
Assert.assertEquals(reader.doneTimes(), 1);
Assert.assertEquals(reader.errorTimes(), 0);
writer = new TestWriter();
reader = new ControlReader();
es = EntityStreams.newEntityStream(writer);
es.addObserver(observer);
es.setReader(reader);
reader.read(1);
writer.write();
writer.error(writeError);
Assert.assertEquals(writer.abortedTimes(), 0);
Assert.assertEquals(reader.getChunkCount(), 1);
Assert.assertEquals(reader.errorTimes(), 1);
}
use of com.linkedin.r2.message.stream.entitystream.Observer in project rest.li by linkedin.
the class TestEntityStream method testRaceBetweenAbnormalAbortAndCancel.
private void testRaceBetweenAbnormalAbortAndCancel(ExecutorService executor) throws Exception {
final CountDownLatch startLatch = new CountDownLatch(1);
final CountDownLatch finishLatch = new CountDownLatch(2);
final CountDownLatch prepareLatch = new CountDownLatch(2);
final TestWriter writer = new TestWriter();
TestObserver observer = new TestObserver();
final ControlReader reader = new ControlReader() {
@Override
public void onDataAvailable(ByteString data) {
try {
prepareLatch.countDown();
startLatch.await();
} catch (Exception ex) {
// ...
}
throw new RuntimeException("broken reader throws");
}
};
EntityStream es = EntityStreams.newEntityStream(writer);
es.addObserver(observer);
es.setReader(reader);
reader.read(1000);
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
while (writer.remaining() > 0) {
writer.write();
}
finishLatch.countDown();
return null;
}
});
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
prepareLatch.countDown();
startLatch.await();
reader.cancel();
finishLatch.countDown();
return null;
}
});
prepareLatch.await();
startLatch.countDown();
Assert.assertTrue(finishLatch.await(1000, TimeUnit.MILLISECONDS));
// we should always fail because cancel on reader side wouldn't cause cancel action if
// writer is already in the writing process
Assert.assertEquals(writer.abortedTimes(), 1);
Assert.assertEquals(observer.errorTimes(), 1);
Assert.assertEquals(observer.getChunkCount(), 1);
Assert.assertEquals(observer.getLastEvent(), "onError");
Assert.assertEquals(reader.errorTimes(), 1);
Assert.assertEquals(reader.getChunkCount(), 0);
}
Aggregations