jsr356-experts@websocket-spec.java.net

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

From: Danny Coward <danny.coward_at_oracle.com>
Date: Wed, 07 Nov 2012 17:58:45 -0800

So folks,

I agree with Scott that this is a good change: to require a new instance
of the Endpoint per session. It greatly simplifies the developer model
in regard to having to deal with multiple threads. Ditto for the POJOs.
So I propose we make this change in the next draft.

The consequences for this change are:-

1) we need to change the server publish method to take the endpoint
class rather than one instance:
ServerContainer.publishServer(Endpoint e, ServerEndpointConfiguration
sec) -> ServerContainer.publishServer(Class<? extends Endpoint>,
ServerEndpointConfiguration sec)

2) client registration: no change - one client instance connects to one URL.

3) drop the Session parameter from Endpoint.onError, Endpoint.onClose as
they are no longer necessary: the Endpoint instance gets the reference
to its (single) Session instance just on the onOpen method.

Let me know if anyone sees any issues with these changes.

Thanks,

- Danny





On 10/29/12 4:57 PM, Danny Coward wrote:
> 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
>


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