Search in sources :

Example 1 with Task

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;
    }));
}
Also used : Engine(com.linkedin.parseq.Engine) Promises(com.linkedin.parseq.promise.Promises) Executor(java.util.concurrent.Executor) BiFunction(java.util.function.BiFunction) Success(com.linkedin.parseq.function.Success) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Consumer(java.util.function.Consumer) SettablePromise(com.linkedin.parseq.promise.SettablePromise) Future(java.util.concurrent.Future) CompletionStage(java.util.concurrent.CompletionStage) Stream(java.util.stream.Stream) ForkJoinPool(java.util.concurrent.ForkJoinPool) Failure(com.linkedin.parseq.function.Failure) BiConsumer(java.util.function.BiConsumer) Task(com.linkedin.parseq.Task) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SettablePromise(com.linkedin.parseq.promise.SettablePromise)

Example 2 with Task

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);
}
Also used : IndividualRequestMap(com.linkedin.restli.common.multiplexer.IndividualRequestMap) IndividualRequest(com.linkedin.restli.common.multiplexer.IndividualRequest) Task(com.linkedin.parseq.Task) ArrayList(java.util.ArrayList) ByteString(com.linkedin.data.ByteString)

Example 3 with Task

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);
    }
}
Also used : FilterRequestContextInternalImpl(com.linkedin.restli.internal.server.filter.FilterRequestContextInternalImpl) RoutingException(com.linkedin.restli.server.RoutingException) Task(com.linkedin.parseq.Task) BaseTask(com.linkedin.parseq.BaseTask) RestLiSyntaxException(com.linkedin.restli.internal.server.util.RestLiSyntaxException) FilterChainDispatcherImpl(com.linkedin.restli.internal.server.filter.FilterChainDispatcherImpl) URI(java.net.URI) RestLiFilterChain(com.linkedin.restli.internal.server.filter.RestLiFilterChain) RoutingResult(com.linkedin.restli.internal.server.RoutingResult) FilterChainCallback(com.linkedin.restli.internal.server.filter.FilterChainCallback) FilterChainDispatcher(com.linkedin.restli.internal.server.filter.FilterChainDispatcher) RestLiResponseHandler(com.linkedin.restli.internal.server.response.RestLiResponseHandler) FilterChainCallbackImpl(com.linkedin.restli.internal.server.filter.FilterChainCallbackImpl) RestLiCallback(com.linkedin.restli.internal.server.RestLiCallback) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) ResourceContextImpl(com.linkedin.restli.internal.server.ResourceContextImpl) RestLiResponse(com.linkedin.restli.internal.server.response.RestLiResponse) RestLiArgumentBuilder(com.linkedin.restli.internal.server.methods.arguments.RestLiArgumentBuilder) CountDownLatch(java.util.concurrent.CountDownLatch) RestLiFilterResponseContextFactory(com.linkedin.restli.internal.server.filter.RestLiFilterResponseContextFactory) RestRequest(com.linkedin.r2.message.rest.RestRequest) Callback(com.linkedin.common.callback.Callback) RestLiCallback(com.linkedin.restli.internal.server.RestLiCallback) FilterChainCallback(com.linkedin.restli.internal.server.filter.FilterChainCallback) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RestLiRequestData(com.linkedin.restli.server.RestLiRequestData)

Example 4 with Task

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));
}
Also used : Task(com.linkedin.parseq.Task) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.testng.annotations.Test) BaseEngineTest(com.linkedin.parseq.BaseEngineTest)

Example 5 with Task

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");
}
Also used : GuavaRateLimiter(com.linkedin.parseq.retry.termination.GuavaRateLimiter) BaseEngineTest(com.linkedin.parseq.BaseEngineTest) Task.withRetryPolicy(com.linkedin.parseq.Task.withRetryPolicy) TimeoutException(java.util.concurrent.TimeoutException) Assert.assertEquals(org.testng.Assert.assertEquals) Assert.assertTrue(org.testng.Assert.assertTrue) Test(org.testng.annotations.Test) RateLimiter(com.linkedin.parseq.retry.termination.RateLimiter) Function(java.util.function.Function) Task(com.linkedin.parseq.Task) TerminationPolicy(com.linkedin.parseq.retry.termination.TerminationPolicy) Task.withRetryPolicy(com.linkedin.parseq.Task.withRetryPolicy) TimeoutException(java.util.concurrent.TimeoutException) BaseEngineTest(com.linkedin.parseq.BaseEngineTest) Test(org.testng.annotations.Test)

Aggregations

Task (com.linkedin.parseq.Task)13 BaseTask (com.linkedin.parseq.BaseTask)4 SettablePromise (com.linkedin.parseq.promise.SettablePromise)4 BaseEngineTest (com.linkedin.parseq.BaseEngineTest)3 Promises (com.linkedin.parseq.promise.Promises)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 Function (java.util.function.Function)3 Test (org.testng.annotations.Test)3 ByteString (com.linkedin.data.ByteString)2 Engine (com.linkedin.parseq.Engine)2 Task.withRetryPolicy (com.linkedin.parseq.Task.withRetryPolicy)2 Failure (com.linkedin.parseq.function.Failure)2 Success (com.linkedin.parseq.function.Success)2 Promise (com.linkedin.parseq.promise.Promise)2 TerminationPolicy (com.linkedin.parseq.retry.termination.TerminationPolicy)2 RestRequest (com.linkedin.r2.message.rest.RestRequest)2 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)2 RestResponse (com.linkedin.r2.message.rest.RestResponse)2 InterfaceType (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor.InterfaceType)2 IOException (java.io.IOException)2