users@grizzly.java.net

Grizzly2 TCPNIOTransport ownership and lifecycle

From: Matthew Swift <matthew.swift_at_oracle.com>
Date: Mon, 29 Nov 2010 11:52:03 +0100

Hi there,

I'm a bit confused by the usage of TCPNIOTransport in
org.glassfish.grizzly.http.server.NetworkListener. For example, the
start() and stop() methods which do the following:

     public synchronized void start() throws IOException {
         ...

         transport.setProcessor(filterChain);
         transport.bind(host, port);
         transport.start();

         ...
     }

     public synchronized void stop() throws IOException {
         ...

         transport.stop();

         ...
     }

Is this reasonable? My understanding was that a TCPNIOTransport is a
resource (incl. thread pool, memory manager, etc) which can be shared
amongst multiple NetworkListeners, and other Grizzly based protocol
implementations. Clearly the NetworkListener implementation is
contradicting my understanding since it assumes ownership of the
transport (these are just two examples of methods doing this, there are
others - e.g. configureThreadPool, pause, resume, etc).

Typically, if I am developing an application which, for example, exposes
multiple front ends such as HTTP and HTTPS (as well as LDAP and LDAPS in
my case) I will want these front ends to share the same TCPNIOTransport
and its associated resources, e.g. its thread pool. This is even more
significant for proxy implementations which of course act as both server
(frontend) and client (backend) simultaneously.

I appreciate that an API should permit each front-end / back-end to use
its own transport, but presumably sharing should be allowed as well,
shouldn't it?

All this leaves me a bit confused about the ownership model and
life-cycle of various core Grizzly classes:

    * What is the ownership model of a TCPNIOTransport? Note that the
      default transport factory uses the same thread pool for all
      transports that it creates, so shutting down one transport will
      shutdown the thread pool for all transports.

    * What is the recommended approach to developing a server
      implementation which has multiple front-ends and/or backends and
      wishes to share the same thread pool and other infrastructure? A
      more fundamental question is: what things should be shared and
      what things should not? By "things" I mean selectors, thread
      pools, memory managers, etc.

Finally, on an unrelated note, I spotted something else while looking at
the NetworkListener implementation: is it possible to create a
NetworkListener with custom filters inserted into the filter chain (e.g.
IdleTimeoutFilter)? At the moment it looks like if I want to do this I
must cut 'n' paste the content of
org.glassfish.grizzly.http.server.HttpServer.configureListener(NetworkListener))
and customize as needed, which seems a bit annoying. Admittedly, I can't
see a generic way of allowing custom filters, since it would require
some mechanism for specifying where the custom filters should be inserted.

As a bit of background, my ultimate goal is to implement a server
application which exposes multiple listener front-ends (e.g. HTTP,
HTTPS, LDAP, LDAPS, etc) as well as having proxy (i.e. client)
functionality in the back-end for accessing potentially many remote
servers using different protocols. I would like all these Grizzly based
components to share the same thread pool and may be the selectors too
(and other infrastructure such as memory support, etc).

Cheers :-)

Matt