use of com.linkedin.parseq.Task in project rest.li by linkedin.
the class ParSeqBasedCompletionStage method produceEitherStageAsync.
private <U> ParSeqBasedCompletionStage<U> produceEitherStageAsync(String taskName, CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor) {
Task<T> that = getOrGenerateTaskFromStage(other);
final AtomicBoolean[] sync = { new AtomicBoolean(false) };
return nextStageByComposingTask(Task.async(taskName, () -> {
final SettablePromise<U> result = Promises.settable();
Stream.of(_task, that).map(task -> task.onFailure(throwable -> {
if (sync[0].compareAndSet(false, true)) {
result.fail(throwable);
}
}).flatMap((t) -> Task.blocking(() -> {
if (sync[0].compareAndSet(false, true)) {
try {
result.done(fn.apply(t));
} catch (Throwable throwable) {
result.fail(throwable);
}
}
return (U) null;
}, executor))).forEach(this::ensureFuture);
return result;
}));
}
use of com.linkedin.parseq.Task in project rest.li by linkedin.
the class MultiplexedRequestHandlerImpl method createParallelRequestsTask.
private Task<?> createParallelRequestsTask(RestRequest envelopeRequest, RequestContext requestContext, IndividualRequestMap individualRequests, IndividualResponseMap individualResponses, Map<String, HttpCookie> responseCookies) {
List<Task<?>> tasks = new ArrayList<>(individualRequests.size());
for (IndividualRequestMap.Entry<String, IndividualRequest> individualRequestMapEntry : individualRequests.entrySet()) {
String id = individualRequestMapEntry.getKey();
IndividualRequest individualRequest = individualRequestMapEntry.getValue();
// create a task for the current request
Task<Void> individualRequestTask = createRequestHandlingTask(id, envelopeRequest, requestContext, individualRequest, individualResponses, responseCookies);
IndividualRequestMap dependentRequests = individualRequest.getDependentRequests();
if (dependentRequests.isEmpty()) {
tasks.add(individualRequestTask);
} else {
// recursively process dependent requests
Task<?> dependentRequestsTask = createParallelRequestsTask(envelopeRequest, requestContext, dependentRequests, individualResponses, responseCookies);
// tasks for dependant requests are executed after the current request's task
tasks.add(individualRequestTask.andThen(dependentRequestsTask));
}
}
return Task.par(tasks);
}
use of com.linkedin.parseq.Task in project rest.li by linkedin.
the class TestRestLiMethodInvocation method checkInvocation.
private void checkInvocation(Object resource, RequestContext requestContext, ResourceMethodDescriptor resourceMethodDescriptor, ResourceMethodConfig resourceMethodConfig, String httpMethod, ProtocolVersion version, String uri, String entityBody, MutablePathKeys pathkeys, final Callback<RestResponse> callback, final boolean isDebugMode, final boolean expectRoutingException, final RestLiAttachmentReader expectedRequestAttachments, final RestLiResponseAttachments expectedResponseAttachments) throws Exception {
assertNotNull(resource);
assertNotNull(resourceMethodDescriptor);
try {
EasyMock.replay(resource);
RestRequestBuilder builder = new RestRequestBuilder(new URI(uri)).setMethod(httpMethod).addHeaderValue("Accept", "application/json").setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, version.toString());
if (entityBody != null) {
builder.setEntity(entityBody.getBytes(Data.UTF_8_CHARSET));
}
if (expectedResponseAttachments != null) {
builder.addHeaderValue(RestConstants.HEADER_ACCEPT, RestConstants.HEADER_VALUE_MULTIPART_RELATED);
}
RestRequest request = builder.build();
if (isDebugMode) {
requestContext.putLocalAttr(RestLiMethodInvoker.ATTRIBUTE_PROMISE_LISTENER, new PromiseListener<Object>() {
@Override
public void onResolved(Promise<Object> promise) {
// PromiseListener is invoked with a task.
if (promise instanceof Task) {
requestContext.putLocalAttr(ATTRIBUTE_PARSEQ_TRACE, ((Task<?>) promise).getTrace());
}
}
});
}
final ServerResourceContext resourceContext = new ResourceContextImpl(pathkeys, request, requestContext);
resourceContext.setRequestAttachmentReader(expectedRequestAttachments);
if (expectedResponseAttachments != null) {
resourceContext.setResponseAttachments(expectedResponseAttachments);
}
RoutingResult routingResult = new RoutingResult(resourceContext, resourceMethodDescriptor, resourceMethodConfig);
RestLiArgumentBuilder argumentBuilder = _methodAdapterProvider.getArgumentBuilder(resourceMethodDescriptor.getType());
RestLiRequestData requestData = argumentBuilder.extractRequestData(routingResult, entityBody != null && !entityBody.isEmpty() ? DataMapUtils.readMapWithExceptions(request) : null);
FilterRequestContext filterContext = new FilterRequestContextInternalImpl(routingResult.getContext(), resourceMethodDescriptor, requestData);
final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch expectedRoutingExceptionLatch = new CountDownLatch(1);
RestLiResponseHandler restLiResponseHandler = new RestLiResponseHandler(_methodAdapterProvider, _errorResponseBuilder);
Callback<RestLiResponse> executionCallback = new Callback<RestLiResponse>() {
@Override
public void onError(Throwable e) {
if (e.getCause() != null && e.getCause().getCause() instanceof RoutingException) {
expectedRoutingExceptionLatch.countDown();
}
if (callback != null) {
callback.onError(e);
}
Assert.assertEquals(resourceContext.getRequestAttachmentReader(), expectedRequestAttachments);
Assert.assertEquals(resourceContext.getResponseAttachments(), expectedResponseAttachments);
latch.countDown();
}
@Override
public void onSuccess(final RestLiResponse result) {
if (callback != null) {
callback.onSuccess(ResponseUtils.buildResponse(routingResult, result));
}
Assert.assertEquals(resourceContext.getResponseAttachments(), expectedResponseAttachments);
latch.countDown();
}
};
FilterChainDispatcher filterChainDispatcher = new FilterChainDispatcherImpl(routingResult, _invoker, argumentBuilder);
FilterChainCallback filterChainCallback = new FilterChainCallbackImpl(routingResult, restLiResponseHandler, executionCallback, _errorResponseBuilder);
final RestLiCallback outerCallback = new RestLiCallback(filterContext, new RestLiFilterResponseContextFactory(request, routingResult, restLiResponseHandler), new RestLiFilterChain(null, filterChainDispatcher, filterChainCallback));
RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), Collections.emptySet(), routingResult.getContext());
_invoker.invoke(requestData, routingResult, argumentBuilder, outerCallback);
try {
latch.await();
if (expectRoutingException) {
expectedRoutingExceptionLatch.await();
}
} catch (InterruptedException e) {
// Ignore
}
EasyMock.verify(resource);
Assert.assertEquals((routingResult.getContext()).getResponseMimeType(), "application/json");
} catch (RestLiSyntaxException e) {
throw new RoutingException("syntax exception", 400);
} finally {
EasyMock.reset(resource);
EasyMock.makeThreadSafe(resource, true);
}
}
use of com.linkedin.parseq.Task in project parseq by linkedin.
the class TestZKClient method testGetChildrenWithWatcher.
@Test
public void testGetChildrenWithWatcher() throws InterruptedException, KeeperException {
final String parent = "/testGetChildrenWithWatcher";
final List<String> children = Arrays.asList(new String[] { "foo", "bar", "baz", "qux" });
final CountDownLatch latch = new CountDownLatch(1);
List<Task<String>> createChildrenTasks = new ArrayList<>(children.size());
for (String child : children) {
createChildrenTasks.add(_zkClient.create(parent + "/" + child, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
}
Task<List<String>> prepare = _zkClient.ensurePathExists(parent).andThen(Tasks.par(createChildrenTasks));
Task<List<String>> getChildren = _zkClient.getChildren(parent).withWatcher(watchEvent -> latch.countDown());
runAndWait("getChildren2", prepare.andThen(getChildren));
Assert.assertTrue(children.containsAll(getChildren.get()) && getChildren.get().containsAll(children));
/* make sure the watcher is not fired */
Assert.assertEquals(latch.getCount(), 1);
/* delete a child */
_zooKeeper.getZooKeeper().delete(parent + "/foo", -1);
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
}
use of com.linkedin.parseq.Task in project parseq by linkedin.
the class TestRetryPolicy method testErrorClassification.
@Test
public void testErrorClassification() {
Function<Throwable, ErrorClassification> errorClassifier = error -> error instanceof TimeoutException ? ErrorClassification.RECOVERABLE : ErrorClassification.UNRECOVERABLE;
RetryPolicy retryPolicy = new RetryPolicyBuilder().setTerminationPolicy(TerminationPolicy.limitAttempts(3)).setErrorClassifier(errorClassifier).build();
assertEquals(retryPolicy.getName(), "RetryPolicy.LimitAttempts");
Task<Void> task1 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new TimeoutException("current attempt: " + attempt)));
runAndWaitException(task1, TimeoutException.class);
assertTrue(task1.isDone());
assertEquals(task1.getError().getMessage(), "current attempt: 2");
Task<Void> task2 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new IllegalArgumentException("current attempt: " + attempt)));
runAndWaitException(task2, IllegalArgumentException.class);
assertTrue(task2.isDone());
assertEquals(task2.getError().getMessage(), "current attempt: 0");
}
Aggregations