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(a)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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/resteasy-dev