jsr356-experts@websocket-spec.java.net

[jsr356-experts] Controlling endpoint instance creation was: Two outstanding issues...

From: Danny Coward <danny.coward_at_oracle.com>
Date: Mon, 25 Feb 2013 16:42:59 -0800

OK, well several of you have voiced a desire for this need to control
creation of instances, I think our ServerEndpointConfigurator could be
extended to play the role and provide the hook.

If all of you that want this are ok with just using the CDI:
javax.annotation.PostConstruct annotation, then please speak up and we
are done ! But I strongly suspect not, so otherwise, please read on:-

The 'EndpointFactory' proposal would be to add what was the old (from
v008!) EndpointFactory.create() method for endpoint instances to todays
ServerEndpointConfigurator.

The developer can already provide a customized
ServerEndpointConfigurator by subtyping it, overriding any of its
methods and either setting it in the ServerEndpointConfigurationBuilder,
or by using the configuration() attribute in @ServerEndpoint.

So if we add the factory method there, the developer can provide his own
implementation of the method. The specification would require that this
method be used if overridden. The container default
ServerEndpointConfigurator would use its existing mechanisms to
instantiate the endpoint instances (i.e. using CDI in the EE case,
public no-arg constructor else).

Specifically, add to ServerEndpointConfigurator

/** (something like) This method is called by the container when it
needs a new
** instance of the endpoint this configurator configures. Developers
** may override this method to control instantiation of
** endpoint instances in order to customize the initialization
** of the endpoint instance, or manage them in some other way.
** If the developer overrides this method, services like
** dependency injection that are otherwise supported
** may not be available.
*/
public Object createEndpoint() throws InstantiationException;

Works equally well for programmatic endpoints and annotated endpoints,
and fits with the existing configuration scheme.

- Danny





On 2/25/13 9:09 AM, Scott Ferguson wrote:
> On 2/25/13 6:27 AM, Joe Walnes wrote:
>> I'll just pipe up and say that I'm still a big supporter of the
>> EndpointFactory approach ;).
>>
>> On the hybrid thing, I don't see it as too complicated: All Endpoints
>> always get constructed through an EndpointFactory, and we include
>> some standard implementations for the default mechanism. Most users
>> will probably just leave the default in place, but for those who need
>> their own control of construction (could be manual, could be through
>> a 3rd party DI library), the hook is there for them without adding
>> too much complexity.
>>
>> It also folds into the other issue... we could defer the singleton
>> question until .next, but users who want it now can do it themselves
>> with a custom EndpointFactory implementation.
>
> I basically agree.
>
> Another alternative is the older "launch websockets from a normal
> servlet" style, which has a side benefit of allowing encapsulation of
> anything available to a normal servlet. In Resin's early websocket
> design, we used something similar to the client publish:
>
> @Inject
> private WebSocketServletContainer container; ... [obtained somehow
> if CDI isn't available]
>
> public void service(ServletRequest req, ServletResponse res)
> {
> Endpoint myEndpoint = ...;
>
> wsSession = container.startWebSocketEndpoint(req, res, myEndpoint);
> }
>
> Possible benefits:
> 1. "myEndpoint" can be instantiated however the application wants,
> including a singleton
> 2. it can encapsulate anything available to a servlet (including the
> session or auth/login/user info)
> 3. allows for dynamic launching (i.e. not fixed URLs)
>
> -- Scott
>
>
>
>
>
>
>
>
>
>>
>> cheers
>> -Joe
>>
>>
>> On Thu, Feb 21, 2013 at 5:58 PM, Danny Coward
>> <danny.coward_at_oracle.com <mailto:danny.coward_at_oracle.com>> wrote:
>>
>> Hi folks,
>>
>> Two last issues from the JIRA that we have not yet covered:
>> bringing back the EndpointFactory, and deploying server endpoints
>> so that only one instance per path is used, rather than a new
>> instance per client.
>>
>> 1) Bringing back the EndpointFactory
>>
>> Joe posted about the EndpointFactory in detail
>> (http://java.net/projects/websocket-spec/lists/jsr356-experts/archive/2013-01/message/2),
>> and we didn't have much discussion about it at the time, but I
>> did log it. Essentially, the EndpointFactory idea allows
>> developer provided code to be run to produce the endpoint
>> instance. So any endpoint instance configuration can happen
>> there. In the *Configuration model we have now, such
>> configuration code has to be located in a developer provided
>> *Configurator class.
>>
>> My own take is that the world of injection frameworks really
>> requires us to allow the containers to instantiate these
>> endpoints, their use is more and more common. While we could
>> absolutely have a hybrid model where if you are not in a DI
>> environment you could supply a factory, and if you are in a DI
>> world you use something like a configurator, I think two models
>> would be just too complicated.
>>
>> We would also still need something like the Configurator if we
>> had EndpointFactory. And we would need the Configuation classes.
>> So, the EndpointFactory approach leads us to a bigger API :(
>>
>> I think functionally, the approaches are equivalent, even if one
>> is the 'inside out' version of the other Factory.create() versus
>> endpoint.onOpen().
>>
>> I think the new configuration apis do address some of the
>> concerns forced by the public no-arg constructor on Endpoint: we
>> have a property bag on the EndpointConfiguration interface for
>> easier sharing of data across instances without having to
>> subtype. We have also de-coupled the Endpoint and the
>> EndpointConfiguration in the newer API: now the same Endpoint
>> class can be deployed in multiple configurations (say, URIs)
>> because the deployment of an Endpoint is done with an
>> EndpointConfiguration instance instead of class.
>>
>> So, not a perfect answer at all for our custom configuration
>> example, but I think a simpler solution overall not to try to
>> bring back the EndpointFactory.
>>
>> Are there any big supporters of the endpoint factory approach ?
>>
>>
>> 2) Allow deployment of server endpoint singletons.
>>
>> The Endpoint API certainly allows for this kind of case where the
>> developer wants a single instance to handle all connections,
>> instead of today's (simpler) model where a new instance is
>> created per connection. You'll probably remember that at first
>> the spec defined endpoint to be singletons, then we decided to
>> opt for the easier single threaded 'one per client' endpoint
>> model because we thought that would make for an easier
>> development model for the more common use cases.
>>
>> Now, all the lifecycle methods take the Session, so the
>> connections can all be disambiguated. Such 'singleton' endpoints
>> would be different from today's 'one per client' endpoints. They
>> would need to be programmed for concurrent incoming
>> events/messages from different clients. The 'singleton' endpoints
>> operate in the context of multiple session objects, the 'one per
>> client' endpoints operate in the context of just one. So, it
>> seems to me, except in the most trivial cases, they are likely to
>> be programmed quite differently, even if they both fit into the
>> Endpoint model.
>>
>> All of which makes me think that we should be distinguishing
>> these two types of server endpoint more formally. Perhaps
>> extended API, perhaps more meta data in the annotations.
>>
>> Which makes me think we should play it safe, stick with the 'one
>> instance per client' model we have, and look at singletons in
>> more detail in .next.
>>
>> Are there any big supporters of the singleton approach ?
>>
>> Thanks,
>>
>> - Danny
>>
>> --
>> <http://www.oracle.com> *Danny Coward *
>> Java EE
>> Oracle Corporation
>>
>>
>


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