jsr356-experts@websocket-spec.java.net

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

From: Danny Coward <danny.coward_at_oracle.com>
Date: Mon, 29 Oct 2012 16:57:42 -0700

On 10/29/12 4:20 PM, Scott Ferguson wrote:
> 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.
Yeah, we'd need a developer-provided instance creation method for
endpoints (either Endpoint constructor or factory method) and since
MessageHandler and Endpoint instances would be 1-1, we might move things
around there too. But I want to make sure everyone thinks its the right
change before we figure out the API consequences.

- d

>
> -- 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
>>
>


-- 
<http://www.oracle.com> 	*Danny Coward *
Java EE
Oracle Corporation