Hello

I'd like to share great news about Pax Web 8 state.

For last few days I was working on tiny, single test related to
Whiteboard-registration of WebSockets...

Normally (WAR) websockets are registered by some
ServletContainerInitializer based ONLY on the classes passed to
SCI.onStartup() and scanned using (usually) the information like this:

@HandlesTypes({
    ServerEndpoint.class,
    ServerApplicationConfig.class,
    Endpoint.class
})

WAR scenario in Pax Web 8 was easy - simply an existing SCI (or custom one
for Undertow) was sufficient.

The problem was the dynamics of Whiteboard approach. What should happen
when you simply "add a websocket"?
Pax Web 7, when registering a websocket was adding an SCI to be invoked at
(re)start time of the target (Jetty, Tomcat, Undertow) context. So easy
calculation - 10 websockets == 10 SCIs.

This fact made me think wider - how restarts and SCIs should be handled?

I got back to most trivial question - how many ways there are to register a
servlet? In Pax Web case there are FIVE:

   1. webcontainer.registerServlet()
   2. Whiteboard registration of javax.servlet.Servlet service
   3. an SCI may invoke servletContext.addServlet()
   4. a ServletContextListener may invoke servletContext.addServlet()
   5. an Undertow extension may add additional servlets to DeploymentInfo

the same is for filters and listeners (except that a ServletContextListener
can't register more ServletContextListeners)

So when we register and SCI that registers a websocket we want it to be
run, right? so we effectively want to "restart a context". But (and that's
what I was working on during last 3 days):

   - we *don't want* to lose servlets/filters/listeners registered
   previously through Whiteboard/HttpService
   - we *want* to lose the servlets/filters/listeners registered by SCIs
   and ServletContextListeners, because if we call them again, we don't want
   conflicts!
   - we *want* to clear the context attributes that could've been set by
   SCIs/ServletContextListeners before, because that's how SCis "mark" the
   context as processed - leaving there some flags that prevents them from
   doing some tasks more than once

And finally I have a working scenario:

   - an SCI is Whiteboard registered and calls sc.addFilter() in onStartup()
   - a ServletContextListener is Whiteboard registered and calls
   sc.setAttribute() and sc.addServlet() in contextInitialized()
   - a servlet is Whiteboard registered
   - a filter is Whiteboard registered
   - a WebSocket (1) is registered by instance
   - a WebSocket (2) is registered by class
   - a WebSocket (2) is unregistered

In between the registrations, GET requests are performed to check the
expected behavior - *and everything works consistently across all 3
container runtimes!*

And yes - I added the possibility to register actual WebSocket instance -
Pax Web 7, even if you've registered a @ServerEndpoint-annotated object as
WebSocket, was simply taking its getClass() and was using this class
(instantiated later by actual runtime).

And what's more - even if you register/unregister more WebSockets, single,
dedicated SCI is used to (re)register all needed WebSockets!

I hope the actual 8.0.0.GA is finally coming.

kind regards
Grzegorz Grzybek

Reply via email to