[resteasy-dev] Extending Resteasy async support (server-side)

Stephane Epardaud stef at epardaud.fr
Fri Aug 11 08:12:55 EDT 2017


OK I am looking at ResourceMethodInvoker and
CompletionStageResponseConsumer and will work on a PR to support other
async types first. Should be the easiest. What you're doing in
CompletionStageResponseConsumer looks _a lot_ like what I had to do to
support it myself in my proto. Except the bit where I have to change the
jaxrsResponse.setGenericType because otherwise I get
CompletionStage<X>.class instead of X.class when I'm looking up
marshallers. Since it appears you do test this, I assume it's somewhere
else?


On 10/08/17 19:18, Ron Sigal wrote:
>
> Hi Stephane,
>
> Wow, that's a lot to digest. ;-)
>
> Have you seen the treatment of CompletionStage in
> org.jboss.resteasy.core.ResourceMethodInvoker. If the resource method
> return type is CompletionStage, ResourceMethodInvoker registers a
> org.jboss.resteasy.core.CompletionStageResponseConsumer that waits for
> a response. CompletionStage is hard coded here, but maybe we could use
> service loading and a ContextResolver to get a method that
>
>   1. verifies that a given class has asynchronous behavior, and
>   2. constructs an appropriate object like
> CompletionStageResponseConsumer to listen for a completed response.
>
> I'll go on to try to digest the rest of your message, but that's a
> start, I hope.
>
> -Ron
>
>
> On 08/10/2017 03:38 AM, Stephane Epardaud wrote:
>> Hi,
>>
>> I'm working on trying to make Resteasy and Vertx integrate better,
>> and while writing a prototype I noticed several things which would
>> need support from Resteasy.
>>
>> The first thing which I need RE to support is that I want to be able
>> to return async types from my resource methods. In JAX-RS 2.0 async
>> resource methods are supported but require a peculiar style, such as
>> taking a "@Suspended AsyncResponse asyncResponse" parameter,
>> returning void, and resuming with
>> asyncResponse.resume(entityOrException).
>>
>> I know JAX-RS 2.1 supports CompletionStage<Response>. This is great,
>> but it doesn't define a pluggable API to support other types such as
>> rxJava. We should really make that be pluggable, so that I can use
>> rx.Single or other async frameworks.
>>
>> ATM I have a prototype which supports CompletionStage and rx.Single,
>> without modifying RE, but it's using CDI validators to intercept the
>> returned value and do the plugging, which is a terrible hack. I
>> couldn't find a way to do this properly with RE because I can't
>> intercept the returned value before it's sent to the marshallers, by
>> which time it's too late to mark the response as async and register
>> on the listeners.
>>
>> Now, because the return type is CompletionStage<X> (or rx.Single<X>
>> doesn't matter), the ResourceMethodInvoker.getGenericReturnType()
>> returns a very unhelpful type, which I can't used to look up the
>> proper marshallers, so again this is something that has to be taken
>> into account.
>>
>> Sometimes I will declare a return type of CompletionStage<Object>
>> because Java doesn't have Union Types and I can't declare it as
>> CompletionStage<Response | MyEntity>, and in that case I have to look
>> up marshallers based on the entity instance's class rather than the
>> declared type. I suppose the same applies to non-async return types.
>> Is it the spec that fixes this looking up of marshallers based on the
>> static return type and not the entity's actual type?
>>
>> Now, I haven't said much about things like Observable or Flowable
>> (async types that emit more than one value), because it's not yet
>> clear in my mind how that would work with RE. In my proto I do
>> support returning such flows and based on how the method is
>> annotated, RE will pick one strategy:
>>
>> - collect all values in a java.util.List and when all done proceed,
>> - send them as HTTP Chunked: marshall and send each value as they are
>> made available
>> - send them as server-sent events but that's a bit weird when it's
>> not plain text
>>
>> Since JAX-RS 2.1 supports server-sent events, that would also be a
>> strategy that makes sense.
>>
>> I have contacted the CDI team to discuss async injection, because I
>> also want to be able to inject instances of X in my resources where
>> there only exists providers of type CompletionStage<X>, which
>> requires a new CDI API to support async resource
>> instantiation/injection. If/when that gets added to CDI, RE will need
>> to be updated to support this async injection.
>>
>> Similarly I also have a problem with interceptors, because sometimes
>> my RE interceptors require resolving of async types before they can
>> go on with the request. For example for authentication or sessions my
>> interceptors have to wait for vert.x to resolve async values before I
>> can check them and proceed with the requests. The wait the
>> interceptor API is written doesn't let me suspend interception. It's
>> be great if it could. Alternately CDI interceptors have an
>> InvocationContext parameter given to the interceptor on which you
>> have to call proceed() in order to proceed. This allows me to delay
>> proceeding until I have all my async values resolved and only then
>> proceed with the call to the next interceptor. That'd work too.
>>
>> And I guess the same applies to Marshallers. I have Template entity
>> objects that I need to marshall and that is done via an async API in
>> vertx, so again I can't entirely marshall the response when the
>> marshaller is called.
>>
>> Last, and least interestingly, I've always been bitten by the fact
>> that ExceptionMappers are global and I can't override them per
>> resource. Sometimes I have UI/HTML resources that need exception
>> mappers that forward to UI pages, and API resources that have to
>> serialise errors into JSON. I've added support for an
>> @WithExceptionMapper(Class<? extends ExceptionMapper>) annotation
>> that you can place on the resource method or class to override the
>> error mapper for this call.
>>
>> WDYT?
>>
>> I'm definitly game for pushing PRs for those things, BTW.
>>
>> How far along are you guys with implementing JAX-RS 2.1 in RE?
>>
>> Cheers.
>>
>>
>> _______________________________________________
>> resteasy-dev mailing list
>> resteasy-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/resteasy-dev
>
> -- 
> My company's smarter than your company (unless you work for Red Hat)
>
>
> _______________________________________________
> resteasy-dev mailing list
> resteasy-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/resteasy-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/resteasy-dev/attachments/20170811/4a3a2830/attachment.html 


More information about the resteasy-dev mailing list