users@jersey.java.net

[Jersey] Re: Event for successful response?

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Wed, 10 Oct 2012 12:42:29 +0200

The way I see it you need to make sure you're not firing any events in the nextRevision() by splitting the method in 2 - create next revision, fire next revision event. Once that's done, one possible solution is a pattern discussed earlier in JAX-RS 2.0 EG; One might be able to leverage async server side API to return a response before exiting the method body, e.g.:

@Path("/objects")
class Objects {
    @POST
    public Response create(@Suspended AsyncResponse ar) {
        // return POST response
        long rev = nextRevision();
        SomeObject obj = new SomeObject(rev);
        ar.resume(Response.created(...).entity(obj).build());

        // continue processing
        fireNextRevisionEvent(rev);
    }
}

However the disadvantage of this solution is that you would keep occupying the I/O processing container worker thread even after there's no more I/O processing for that request/response exchange, which is generally a bad practice and which is why I was opposing the proposal. In any case, I'm mentioning this here in case you want to chime in.

Also, FWIW, the design where a server depends on a client receiving some HTTP response seems flawed. It seems to me that you're trying to solve a client-side synchronization issue on the server side to prevent client from receiving a WebSocket event before receiving a response for the POST request. If I'm right in my assumption, you may want to look at your client side code and try to tackle the issue there instead.

Marek

On Sep 30, 2012, at 2:16 AM, Sven Jacobs <mail_at_svenjacobs.com> wrote:

> Ok, I have the following problem:
>
> Let's say we have two REST resources /objects and /notifications. /notifications is a WebSocket resource provided by the Atmosphere framework.
> Let's say a client POSTs to /objects to create a new resource.
>
> Pseudocode
>
> @Path("/objects")
> class Objects {
> @POST
> public Response create() {
> long rev = nextRevision();
> SomeObject obj = new SomeObject(rev);
> return Response.created(...).entity(obj).build();
> }
> }
>
> nextRevision() increases the global revision number and fires an internal event. The /notifications resource listens for the event and sends a WebSocket message to all connected clients saying "Hey, I have a new object resource with revision x".
> The problem here is that the WebSocket notification is send before the client received the response from the /objects POST request. So what I'd like to do is put the code which fires the internal revision event at a place where I'm certain that the client first received the POST response from /objects.
>
> 2012/9/30 Martin Matula <martin.matula_at_oracle.com>
> Hi,
> Not at the moment. Can you provide more info on your use-case? Maybe a writer interceptor could be used if you are using Jersey 2.
> Martin
>
>
> On 9/29/12 12:23 PM, Sven Jacobs wrote:
> I would like to perform some action *after* a successful REST response has been send.
> For example:
>
> @Path("/")
> class Example {
> @GET
> public String example() {
> return "Hello world"; // How to perform some action after the response has been send?
> }
> }
>
> Is there some kind of event handler I can inject and add a listener or something like that?
>
> Thanks
>
> Sven
>
>