You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Co...@eng.sun.com on 2000/01/06 22:30:05 UTC

Proposal: request processing cleanup

Existing model

The current request processing is implemented in:

   * ContextManager - it's the entry point used by Adapters ( service()
     method is called after Request/Response is generated).
   * Context - implements the ServletContext API, except mappings.
   * Container - keeps all the mappings defined in context, and all the
     ServletWrappers.
   * RequestMapper - implements the alghoritm used to find the servlet
     inside a Container.
   * LookupResult - The servlet associated with a URI, plus path info
     and servlet path
   * RequestDispatcherImpl - will create a new LookupResult and use it
     to create a sub-request
   * InvokerServlet - if no servlet is found in Context/Container, it
     will generate a new one using defaults.
   * DefaultServlet - for non-servlet resources.
   * Request - URI, headers, attributes - and some informations
     generated by the rest of the  code ( overlaps with LookupResult )
   * Interceptors - Context and ServletWrapper will call Lifecycle and
     Service interceptors.

When a request is generated by Adapter, ContextManager will parse the
URI, find the Context and delegate the processing to it.

The Context will delegate it to Container, which will create a new
RequestMapper that will do  a second parsing and return a LookupResult,
and then delegate to the resulted ServletWrapper.  Context and
ServletWrapper will also call a list of Interceptors.

( this is based on my understanding of the code :-)

New model.

This model is based on Interceptors and use the same semantics/alghoritm
as Apache (and NSAPI, ISAPI !!) -  each request ( or sub-request) will
follow the same path,  with several types of Interceptors processing the
request in a specific way.

In addition to the Lifecycle and Service Interceptors ( and the
SecurityInterceptors as defined by J2EE or Craig's security package), we
will have interceptors that will  parse the URI and set the Context,
ServletWrapper and all other informations required by the spec.


   * Request - same role ( changes: move LookupResult functionality
     inside Request, RequestDispatcher will create a subrequest instead
     of using LookupResult )
   * ContextManager - same role, but instead of hardcoded parsing of the
     request to find a Context it will call a a set of translation
     Interceptors == RequestHandlers ( configurable - the current code
     will be the default !).
   * Interceptor ( or RequestHandler ??  ) - will process the request.
     The current parsing code from RequestMapper, ContextManager,
     InvokerServlet, Container, etc will be moved in one or many
     handlers.

The initial implementation will use the existing code to parse the URI
and
find the Context, ServletWrapper, pathInfo, servletPath, etc and set
them
in the Request object.

( please also read the Apache docs&code, with Request==request_struct,
ServletWrapper==handler, Context==per_dir_config,  Interceptor=handler
method in a module, etc. )

Notes

   * it cleans up existing code. The current code is the result of a
     long evolution ( including the introduction of RequestDispatcher
     and the current semantics of Context), we need something simpler
     and easier to follow.
   * allow better integration with web servers.  This model is similar (
     or identical?) with Apache request processing and few other
     servers.
   * Will help improve the standalone server - it can use a different
     set of Interceptors, and it is easier to experiment with faster
     parsers
   * You can customize tomcat for specific tasks. For example, if a
     server has only one context and no virtual hosts it can use a
     simple interceptor and cut 1/2 of the size ( embeded? ). This will
     also fix several virtual-host problems in the existing code.
   * it will keep the critical path in one place, and IMHO it will be
     easier to read and understand.
   * Craig: It is a specific way to process the request - with 2
     Container layers: ContextManager and ServletWrapper. It is a
     particular implementation of Container - it doesn't prevent the
     hierarchy of containers as in your proposal (2.2.1).

Implementation

I made few experiments and the changes doesn't affect too much outside
core.
Most of the code is written, and assuming no absolute -1 is raised most
of
code can be reorganized in 1-2 weeks.

The first step is to merge LookupResult and Request, and change
RequestDispatcherImpl and the other classes acordingly. Second,
RequestMapper must be transformed into an Interceptor ( i.e. made
stateless ).

The code from ContextManager can be moved in a Interceptor ( that will
parse the URI and set the Context - if none is already there !).

Some code from Context will go into SessionInterceptor - that will
further decouple the session-related code.

Container.lookupServlet will be part another interceptor ( or merged
with ContextInterceptor, and use same parsing code ).

Re: Proposal: request processing cleanup

Posted by Assaf Arkin <ar...@exoffice.com>.
"Anil K. Vijendran" wrote:
> 
> I think what you are asking for are notions like:
> 
>   1. server-level interceptors (global)
>   2. context-level interceptors (per-context)
>   3. session-level interceptors (per-session)
> 
> All requests are processed by the global interceptors.

+1 Ordering is very important


> Context-level interceptors are notified of context lifecycle events as well as
> when a request is being serviced by a particular context.

+1 Ordering might be less important

 
> Session interceptors are notified of session-life cycle events as well as when
> a request is made for a particular session.

The interceptor will be called per session, but the interceptor can only
be configured per context.

arkin

> 
> Ordering needs to be defined for all these.
> 
> I didn't see interceptors with different granularities in Costin's proposal.
> But I suspect it would be possible to add these when the new cleanedup
> infrastructure is in place.
> 
> Assaf Arkin wrote:
> 
> > How can the following be achieved with the new design:
> >
> > Add a global interceptor used by all contexts (e.g. a logging
> > interceptor, security, etc) that must be executed before some
> > Interceptors (and the Servlet itself) but after other interceptors ( at
> > least the one that determines the context)?
> >
> > Be able to start/stop a specific context without affecting the other
> > contexts? If a context is now served by an Interceptor, could that
> > Interceptor expose some management functionality?
> >
> > Could the SessionInterceptor be aware of a session's access boundaries
> > (i.e. begin/end of service request for that session) so that sessions
> > can be load balanced and persisted? Could (should?) the
> > SessionInterceptor be used to terminate a session?
> >
> > Discovery of all contexts in the server so an Interceptor can be
> > configured externally but the configuration will correspond to contexts
> > set in the server?
> >
> > arkin
> >
> > > New model.
> > >
> > > This model is based on Interceptors and use the same semantics/alghoritm
> > > as Apache (and NSAPI, ISAPI !!) -  each request ( or sub-request) will
> > > follow the same path,  with several types of Interceptors processing the
> > > request in a specific way.
> > >
> > > In addition to the Lifecycle and Service Interceptors ( and the
> > > SecurityInterceptors as defined by J2EE or Craig's security package), we
> > > will have interceptors that will  parse the URI and set the Context,
> > > ServletWrapper and all other informations required by the spec.
> > >
> > >    * Request - same role ( changes: move LookupResult functionality
> > >      inside Request, RequestDispatcher will create a subrequest instead
> > >      of using LookupResult )
> > >    * ContextManager - same role, but instead of hardcoded parsing of the
> > >      request to find a Context it will call a a set of translation
> > >      Interceptors == RequestHandlers ( configurable - the current code
> > >      will be the default !).
> > >    * Interceptor ( or RequestHandler ??  ) - will process the request.
> > >      The current parsing code from RequestMapper, ContextManager,
> > >      InvokerServlet, Container, etc will be moved in one or many
> > >      handlers.
> > >
> > > The initial implementation will use the existing code to parse the URI
> > > and
> > > find the Context, ServletWrapper, pathInfo, servletPath, etc and set
> > > them
> > > in the Request object.
> > >
> > > ( please also read the Apache docs&code, with Request==request_struct,
> > > ServletWrapper==handler, Context==per_dir_config,  Interceptor=handler
> > > method in a module, etc. )
> > >
> > > Notes
> > >
> > >    * it cleans up existing code. The current code is the result of a
> > >      long evolution ( including the introduction of RequestDispatcher
> > >      and the current semantics of Context), we need something simpler
> > >      and easier to follow.
> > >    * allow better integration with web servers.  This model is similar (
> > >      or identical?) with Apache request processing and few other
> > >      servers.
> > >    * Will help improve the standalone server - it can use a different
> > >      set of Interceptors, and it is easier to experiment with faster
> > >      parsers
> > >    * You can customize tomcat for specific tasks. For example, if a
> > >      server has only one context and no virtual hosts it can use a
> > >      simple interceptor and cut 1/2 of the size ( embeded? ). This will
> > >      also fix several virtual-host problems in the existing code.
> > >    * it will keep the critical path in one place, and IMHO it will be
> > >      easier to read and understand.
> > >    * Craig: It is a specific way to process the request - with 2
> > >      Container layers: ContextManager and ServletWrapper. It is a
> > >      particular implementation of Container - it doesn't prevent the
> > >      hierarchy of containers as in your proposal (2.2.1).
> > >
> > > Implementation
> > >
> > > I made few experiments and the changes doesn't affect too much outside
> > > core.
> > > Most of the code is written, and assuming no absolute -1 is raised most
> > > of
> > > code can be reorganized in 1-2 weeks.
> > >
> > > The first step is to merge LookupResult and Request, and change
> > > RequestDispatcherImpl and the other classes acordingly. Second,
> > > RequestMapper must be transformed into an Interceptor ( i.e. made
> > > stateless ).
> > >
> > > The code from ContextManager can be moved in a Interceptor ( that will
> > > parse the URI and set the Context - if none is already there !).
> > >
> > > Some code from Context will go into SessionInterceptor - that will
> > > further decouple the session-related code.
> > >
> > > Container.lookupServlet will be part another interceptor ( or merged
> > > with ContextInterceptor, and use same parsing code ).
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
> 
> --
> Peace, Anil +<:-)
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org

Re: Proposal: request processing cleanup

Posted by "Anil K. Vijendran" <An...@eng.sun.com>.
I think what you are asking for are notions like:

  1. server-level interceptors (global)
  2. context-level interceptors (per-context)
  3. session-level interceptors (per-session)

All requests are processed by the global interceptors.

Context-level interceptors are notified of context lifecycle events as well as
when a request is being serviced by a particular context.

Session interceptors are notified of session-life cycle events as well as when
a request is made for a particular session.

Ordering needs to be defined for all these.

I didn't see interceptors with different granularities in Costin's proposal.
But I suspect it would be possible to add these when the new cleanedup
infrastructure is in place.

Assaf Arkin wrote:

> How can the following be achieved with the new design:
>
> Add a global interceptor used by all contexts (e.g. a logging
> interceptor, security, etc) that must be executed before some
> Interceptors (and the Servlet itself) but after other interceptors ( at
> least the one that determines the context)?
>
> Be able to start/stop a specific context without affecting the other
> contexts? If a context is now served by an Interceptor, could that
> Interceptor expose some management functionality?
>
> Could the SessionInterceptor be aware of a session's access boundaries
> (i.e. begin/end of service request for that session) so that sessions
> can be load balanced and persisted? Could (should?) the
> SessionInterceptor be used to terminate a session?
>
> Discovery of all contexts in the server so an Interceptor can be
> configured externally but the configuration will correspond to contexts
> set in the server?
>
> arkin
>
> > New model.
> >
> > This model is based on Interceptors and use the same semantics/alghoritm
> > as Apache (and NSAPI, ISAPI !!) -  each request ( or sub-request) will
> > follow the same path,  with several types of Interceptors processing the
> > request in a specific way.
> >
> > In addition to the Lifecycle and Service Interceptors ( and the
> > SecurityInterceptors as defined by J2EE or Craig's security package), we
> > will have interceptors that will  parse the URI and set the Context,
> > ServletWrapper and all other informations required by the spec.
> >
> >    * Request - same role ( changes: move LookupResult functionality
> >      inside Request, RequestDispatcher will create a subrequest instead
> >      of using LookupResult )
> >    * ContextManager - same role, but instead of hardcoded parsing of the
> >      request to find a Context it will call a a set of translation
> >      Interceptors == RequestHandlers ( configurable - the current code
> >      will be the default !).
> >    * Interceptor ( or RequestHandler ??  ) - will process the request.
> >      The current parsing code from RequestMapper, ContextManager,
> >      InvokerServlet, Container, etc will be moved in one or many
> >      handlers.
> >
> > The initial implementation will use the existing code to parse the URI
> > and
> > find the Context, ServletWrapper, pathInfo, servletPath, etc and set
> > them
> > in the Request object.
> >
> > ( please also read the Apache docs&code, with Request==request_struct,
> > ServletWrapper==handler, Context==per_dir_config,  Interceptor=handler
> > method in a module, etc. )
> >
> > Notes
> >
> >    * it cleans up existing code. The current code is the result of a
> >      long evolution ( including the introduction of RequestDispatcher
> >      and the current semantics of Context), we need something simpler
> >      and easier to follow.
> >    * allow better integration with web servers.  This model is similar (
> >      or identical?) with Apache request processing and few other
> >      servers.
> >    * Will help improve the standalone server - it can use a different
> >      set of Interceptors, and it is easier to experiment with faster
> >      parsers
> >    * You can customize tomcat for specific tasks. For example, if a
> >      server has only one context and no virtual hosts it can use a
> >      simple interceptor and cut 1/2 of the size ( embeded? ). This will
> >      also fix several virtual-host problems in the existing code.
> >    * it will keep the critical path in one place, and IMHO it will be
> >      easier to read and understand.
> >    * Craig: It is a specific way to process the request - with 2
> >      Container layers: ContextManager and ServletWrapper. It is a
> >      particular implementation of Container - it doesn't prevent the
> >      hierarchy of containers as in your proposal (2.2.1).
> >
> > Implementation
> >
> > I made few experiments and the changes doesn't affect too much outside
> > core.
> > Most of the code is written, and assuming no absolute -1 is raised most
> > of
> > code can be reorganized in 1-2 weeks.
> >
> > The first step is to merge LookupResult and Request, and change
> > RequestDispatcherImpl and the other classes acordingly. Second,
> > RequestMapper must be transformed into an Interceptor ( i.e. made
> > stateless ).
> >
> > The code from ContextManager can be moved in a Interceptor ( that will
> > parse the URI and set the Context - if none is already there !).
> >
> > Some code from Context will go into SessionInterceptor - that will
> > further decouple the session-related code.
> >
> > Container.lookupServlet will be part another interceptor ( or merged
> > with ContextInterceptor, and use same parsing code ).
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org

--
Peace, Anil +<:-)



Re: Proposal: request processing cleanup

Posted by Co...@eng.sun.com.
> > Management is not the job of interceptors either - use the existing APIs
> > or add new APIs.
>
> I guess I'll have to rephrase my question. Given that some Interceptors
> can affect the behavior of the server, should management be performed in
> the server or should it be delegated into the Interceptor.

This is the big difference between Interceptors and Apache modules.
I'll return to this a bit later with all the details on "initialization
cleanup".
The ideea is the same as in Craig's proposal - we configure Containers
( i.e. Context, Server, Servlet, etc) - Interceptors are just used as
implementation.

We will be able to configure Interceptors , and the management
should be able to change this - but Interceptors _are_not_ managing
the server ( in the way Apache modules do that ).



> If an Interceptor is now responsible to handle processing for a context,
> what would be the proper way to control that context: should I use that
> particular Interceptor (e.g. ContextInterceptor) as my admin API, or
> should I use ContextConfig (or anything else) as my admin API?

Use Context methods to configure Context.
The admin API should be able to configure Interceptors too, but
we should not abuse that - standard interceptors are supposed to
operate on the defined components as required by the specs,
and "custom" interceptors are supposed to do fine tuning or
special stuff.


> > > Could the SessionInterceptor be aware of a session's access boundaries
> > > (i.e. begin/end of service request for that session) so that sessions
> > > can be load balanced and persisted?
> >
> > It's up to the SessionInterceptor, the model doesn't prevent this.
>
> Question is: is SessionInterceptor called immediately prior-to/after
> using a session and can the SessionInterceptor be called upon to provide
> the session (e.g. automatically retrieving it from persistent storage if
> none existed before)?

Re: Proposal: request processing cleanup

Posted by Assaf Arkin <ar...@exoffice.com>.
> The order of the interceptors and what interceptors are called is
> configurable.

Great.


> Management is not the job of interceptors either - use the existing APIs
> or add new APIs.

I guess I'll have to rephrase my question. Given that some Interceptors
can affect the behavior of the server, should management be performed in
the server or should it be delegated into the Interceptor.

If an Interceptor is now responsible to handle processing for a context,
what would be the proper way to control that context: should I use that
particular Interceptor (e.g. ContextInterceptor) as my admin API, or
should I use ContextConfig (or anything else) as my admin API?

The second case works today, but the second case has a limitation. If I
change ContextInterceptor to MyOwnContextInterceptor, I might not be
able to use ContextConfig to control that context any more.


> > Could the SessionInterceptor be aware of a session's access boundaries
> > (i.e. begin/end of service request for that session) so that sessions
> > can be load balanced and persisted?
> 
> It's up to the SessionInterceptor, the model doesn't prevent this.

Question is: is SessionInterceptor called immediately prior-to/after
using a session and can the SessionInterceptor be called upon to provide
the session (e.g. automatically retrieving it from persistent storage if
none existed before)?


> The SessionInterceptor may terminate sessions - but it's up to the
> implementation of the interceptor, not in core.

OK.


> > Discovery of all contexts in the server so an Interceptor can be
> > configured externally but the configuration will correspond to contexts
> > set in the server?
> 
> It's a different story - server management should be independent of the
> request processing model.

Yes. But the request processing model is affected by configuration, and
there must be some way to configure the stuff.

All the Tomcat internal interceptors will use Tomcat configuration, but
an external interceptor might want to use an external configuration and
have it synchronized.

For example, in Tyrex I could define different transaction/JDBC models
that map to different contexts in Tomcat. Precisely how I implement the
mapping and what Tomcat does internally (the request processing model)
is irrelevant, I just need a *consistent and well defined* way to
associate a Tomcat context with a Tyrex context.

It will most probably not affect your design choices (which, BTW I like
very much!), only require a more explicit definition.

arkin

> 
> Costin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org

Re: Proposal: request processing cleanup

Posted by Co...@eng.sun.com.
Assaf Arkin wrote:

> How can the following be achieved with the new design:
>
> Add a global interceptor used by all contexts (e.g. a logging
> interceptor, security, etc) that must be executed before some
> Interceptors (and the Servlet itself) but after other interceptors ( at
> least the one that determines the context)?

The order of the interceptors and what interceptors are called is
configurable.

Take a look at httpd.conf - inteceptor==module.



> Be able to start/stop a specific context without affecting the other
> contexts? If a context is now served by an Interceptor, could that
> Interceptor expose some management functionality?

It's orthogonal - have nothing to do with the way a request is processed,
and it's not the job of an Interceptor.

When a request is started/stoped we can have some "ContextStatus"
interceptors, but that's another issue.

Management is not the job of interceptors either - use the existing APIs
or add new APIs.

> Could the SessionInterceptor be aware of a session's access boundaries
> (i.e. begin/end of service request for that session) so that sessions
> can be load balanced and persisted?

It's up to the SessionInterceptor, the model doesn't prevent this.

> Could (should?) the SessionInterceptor be used to terminate a session?

It is called only when a request comes, the session is terminated on timeout.

The SessionInterceptor may terminate sessions - but it's up to the
implementation of the interceptor, not in core.

> Discovery of all contexts in the server so an Interceptor can be
> configured externally but the configuration will correspond to contexts
> set in the server?

It's a different story - server management should be independent of the
request processing model.

Costin


Re: Proposal: request processing cleanup

Posted by Assaf Arkin <ar...@exoffice.com>.
How can the following be achieved with the new design:

Add a global interceptor used by all contexts (e.g. a logging
interceptor, security, etc) that must be executed before some
Interceptors (and the Servlet itself) but after other interceptors ( at
least the one that determines the context)?

Be able to start/stop a specific context without affecting the other
contexts? If a context is now served by an Interceptor, could that
Interceptor expose some management functionality?

Could the SessionInterceptor be aware of a session's access boundaries
(i.e. begin/end of service request for that session) so that sessions
can be load balanced and persisted? Could (should?) the
SessionInterceptor be used to terminate a session?

Discovery of all contexts in the server so an Interceptor can be
configured externally but the configuration will correspond to contexts
set in the server?

arkin



> New model.
> 
> This model is based on Interceptors and use the same semantics/alghoritm
> as Apache (and NSAPI, ISAPI !!) -  each request ( or sub-request) will
> follow the same path,  with several types of Interceptors processing the
> request in a specific way.
> 
> In addition to the Lifecycle and Service Interceptors ( and the
> SecurityInterceptors as defined by J2EE or Craig's security package), we
> will have interceptors that will  parse the URI and set the Context,
> ServletWrapper and all other informations required by the spec.
> 
>    * Request - same role ( changes: move LookupResult functionality
>      inside Request, RequestDispatcher will create a subrequest instead
>      of using LookupResult )
>    * ContextManager - same role, but instead of hardcoded parsing of the
>      request to find a Context it will call a a set of translation
>      Interceptors == RequestHandlers ( configurable - the current code
>      will be the default !).
>    * Interceptor ( or RequestHandler ??  ) - will process the request.
>      The current parsing code from RequestMapper, ContextManager,
>      InvokerServlet, Container, etc will be moved in one or many
>      handlers.
> 
> The initial implementation will use the existing code to parse the URI
> and
> find the Context, ServletWrapper, pathInfo, servletPath, etc and set
> them
> in the Request object.
> 
> ( please also read the Apache docs&code, with Request==request_struct,
> ServletWrapper==handler, Context==per_dir_config,  Interceptor=handler
> method in a module, etc. )
> 
> Notes
> 
>    * it cleans up existing code. The current code is the result of a
>      long evolution ( including the introduction of RequestDispatcher
>      and the current semantics of Context), we need something simpler
>      and easier to follow.
>    * allow better integration with web servers.  This model is similar (
>      or identical?) with Apache request processing and few other
>      servers.
>    * Will help improve the standalone server - it can use a different
>      set of Interceptors, and it is easier to experiment with faster
>      parsers
>    * You can customize tomcat for specific tasks. For example, if a
>      server has only one context and no virtual hosts it can use a
>      simple interceptor and cut 1/2 of the size ( embeded? ). This will
>      also fix several virtual-host problems in the existing code.
>    * it will keep the critical path in one place, and IMHO it will be
>      easier to read and understand.
>    * Craig: It is a specific way to process the request - with 2
>      Container layers: ContextManager and ServletWrapper. It is a
>      particular implementation of Container - it doesn't prevent the
>      hierarchy of containers as in your proposal (2.2.1).
> 
> Implementation
> 
> I made few experiments and the changes doesn't affect too much outside
> core.
> Most of the code is written, and assuming no absolute -1 is raised most
> of
> code can be reorganized in 1-2 weeks.
> 
> The first step is to merge LookupResult and Request, and change
> RequestDispatcherImpl and the other classes acordingly. Second,
> RequestMapper must be transformed into an Interceptor ( i.e. made
> stateless ).
> 
> The code from ContextManager can be moved in a Interceptor ( that will
> parse the URI and set the Context - if none is already there !).
> 
> Some code from Context will go into SessionInterceptor - that will
> further decouple the session-related code.
> 
> Container.lookupServlet will be part another interceptor ( or merged
> with ContextInterceptor, and use same parsing code ).