jsr356-experts@websocket-spec.java.net

[jsr356-experts] Re: [jsr356-users] Re: Instances and lifecycles for annotated endpoints

From: Scott Ferguson <ferg_at_caucho.com>
Date: Mon, 29 Oct 2012 16:20:42 -0700

On 10/29/12 3:46 PM, Danny Coward wrote:
> On 10/26/12 7:13 PM, Scott Ferguson wrote:
>> http://java.net/jira/browse/WEBSOCKET_SPEC-21
>> http://java.net/jira/browse/WEBSOCKET_SPEC-37
>>
>> This is an important issue.
>>
>> In particular, the @WebSocketMessage methods really want to operate
>> on beans that are scoped to the connection/session (using the
>> standard @PostConstruct, @PreDestroy for lifecycle.) They're
>> basically MessageHandlers, not endpoints, and should have the same
>> lifecycle as MessageHandlers.
>>
>> The @WebSocketOpen could be scoped to the application (as current,
>> i.e. as Endpoint), but it might be cleaner to change it as well to be
>> called on a new instance for each request (as if MessageHandler), to
>> avoid recreating the old home/instance EJB model. Either way would be
>> logical, but having a single lifecycle in the spec would be simpler
>> to define/explain.
>>
>> So I'd suggest the cleanest change would be to instantiate a new
>> instance for each connection/session.
> I think I agree with you Scott.

>
> The programmatic model in EDR is such that there is one instance of an
> Endpoint per URL-path, and developers have the option of either
> creating new MessageHandler instances per session, or of using the
> same instance for all sessions. What we wrote about threading says
> their lifecycle (onOpen, onClose, onError) methods may be called
> concurrently, but for each session, the onMessage methods will be
> called sequentially.
>
> So its a sort of hybrid, with a single threaded model for the
> MessageHandlers and a multi-threaded (servlet-like) model for the
> Endpoint instances (see section 7.1). I remember this arose back in
> the summer from a discussion we had on threading.

Right. I've implemented this and used it for some prototype services. It
works very well in the non-annotation case.

>
> The annotation model is servlet-like, multiple threads can be in any
> of the annotated methods.

... and this is the difficulty (because messages aren't stateless like
servlet requests are) ...
>
> After presenting this to the EE leads, there was a lot of feedback to
> make the model simpler for developers: a new instance of Endpoint per
> session/connection. i.e. the default mode for Endpoint is CDI request
> scoped in the EE setting. Then all of onOpen, onClose, onError AND
> onMessage are all callbacks in the context of one session/connection,
> and called with only one thread at a time.
>
> Annotated POJOs would then assume the same cardinality: a new POJO
> instance per connection (per VM). Any of the websocket annotated
> methods called by one thread at a time.

Right, for the annotation model this would be perfect.

I'm not sure I understand how the Endpoint change would work for the
non-annotation model. Are you also suggesting changing the
ServerContainer registration to something like:

   interface ServerContainer {
     void publishServer(Class<? extends Endpoint> endpointClass,
                                  ServerEndpointConfiguration cfg);
   }

where endpointClass could instead be something like an EndpointFactory.

An interesting effect is that MessageHandler could become stateless. Or
possibly removed entirely (?) if the Endpoint class itself was
introspected using the same @WebSocketMessage.

-- Scott

>
> How do the others feel about defining things this way ?
>
> Thanks,
>
> - Danny
>
>
>
>
>
>
>
>
>>
>> (Also, I assume each onMessage is in a new CDI RequestScope (?))
>>
>> (Also, the 7.3.2 CDI injection into MessageHandlers doesn't make
>> sense to me. In the current API, the developer instantiates the
>> handler and therefore it would be weird for CDI to inject anything.)
>>
>> -- Scott
>>
>
>
> --
> <http://www.oracle.com> *Danny Coward *
> Java EE
> Oracle Corporation
>