You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by Harmeet Bedi <hb...@yahoo.com> on 2001/03/22 06:19:16 UTC

method execution in protocol handlers and alternative ideas on method processing

Most portocol handlers have some state and methods. This could be simple as
in SMTP(few methods, and connection state) or HTTP to more complicated
protocols like FTP(many state objects and more than a dozen methods with
variations).

Here are some patters/variants that to execute the methods in a handler.

1.
All the code lies in a single switch statement.
The code pattern is
if method == 'foo':
  do something, read input, alter state, write output
else if method == 'bar':
  do something, read input, alter state, write output
else if method == 'shoo':
  do something, read input, alter state, write output
else if method == 'boo':
  do something, read input, alter state, write output
else
  unknow state, write error message
Examples are: POP3Handler, SMTPHandler in James.

2.
The execution code for each method is in a separate function.
The code pattern is
if method == 'foo':
  doFoo(..)
else if method == 'bar':
  doBar(..)
else if method == 'shoo':
  doShoo(..)
else if method == 'boo':
  doBoo(..)
else
   doUnknownCommand()
Examples are: javax.server.http.HttpServlet. The base servlet calls
dispatches processing to different methods and these methods can be
overridden in derived classses.
One variant to manage is to have method invocation based on Reflection and
method name. In a way this is like command pattern with in which Method
becomes a object and object
instance becomes the context to method.

3.
The execution code for each method is in separate class.
The code pattern is
if method == 'foo':
  new Foo().invoke()
else if method == 'bar':
  new Bar().invoke()
else if method == 'shoo':
  new Shoo(..).invoke()
else if method == 'boo':
  new Boo(..).invoke()
else
  new Unknown(..).invoke()
Examples are: jakarta-slide project.
One simple and good variant is to have Object construction via Reflection .
This does away with some more if-then-else code. This makes it easy to
alter/extend the behavior of methods or fix bugs in a compartmentalized
manner.

I feel 2 and 3 are easier to mentain than 1. This becames esp. important as
the
protocol complexity increases. This and state objects can make the
system easier on the reader.

I am attaching the 3 types of implementations for SMTPHandler. The
SMTPHandler is really simple, so it was easy for me to do but it does not
really show off the difference in styles as well as a more complex protocol
server.

What do you think of the different patterns?
Are there others ? Would you prefer one over the other.

My preference is the third pattern, it makes it simple and yields
OO gains.

Would it make sense to move the servers in James from style 1 to style 2 or
3 ?

Harmeet


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
----- Original Message -----
From: "Peter Donald" <do...@apache.org>
Sent: Wednesday, March 21, 2001 10:59 PM


> At 10:16  21/3/01 -0800, Harmeet Bedi wrote:
> >I built production FTP and LDAP Servers, played around prototyped SMTP,
NNTP
> >and HTTP Servers.
>
> I have always wanted to build a LDAP/Directory server for kicks - thought
> about asking the javaldap developer
> (http://sourceforge.net/projects/javaldap) if he would release it under a
> BSD license - but like most things never had the time.


I think having an LDAP Server as part of James, for user management, address
book etc. would help round things up.

Netscape Java SDK contains good stuff, from which a server can be built.

Harmeet
>
> >SMTPController
> >this seems interesting and useful, it sounds a bit like interceptors in
> >Tomcat. Did I get the analogue right ?
>
> essentially - less generic than interceptors I guess. The
> "questions/pluggable-logic" that the controllers are asked are much more
> focused in SMTP but in others (like FTPController they are much more like
> tc3.x interceptros).
>
> Cheers,
>
> Pete
>
> *-----------------------------------------------------*
> | "Faced with the choice between changing one's mind, |
> | and proving that there is no need to do so - almost |
> | everyone gets busy on the proof."                   |
> |              - John Kenneth Galbraith               |
> *-----------------------------------------------------*
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: james-dev-help@jakarta.apache.org



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Peter Donald <do...@apache.org>.
At 10:16  21/3/01 -0800, Harmeet Bedi wrote:
>I built production FTP and LDAP Servers, played around prototyped SMTP, NNTP
>and HTTP Servers.

I have always wanted to build a LDAP/Directory server for kicks - thought
about asking the javaldap developer
(http://sourceforge.net/projects/javaldap) if he would release it under a
BSD license - but like most things never had the time.

>SMTPController
>this seems interesting and useful, it sounds a bit like interceptors in
>Tomcat. Did I get the analogue right ?

essentially - less generic than interceptors I guess. The
"questions/pluggable-logic" that the controllers are asked are much more
focused in SMTP but in others (like FTPController they are much more like
tc3.x interceptros).

Cheers,

Pete

*-----------------------------------------------------*
| "Faced with the choice between changing one's mind, |
| and proving that there is no need to do so - almost |
| everyone gets busy on the proof."                   |
|              - John Kenneth Galbraith               |
*-----------------------------------------------------*


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
----- Original Message -----
From: "Serge Knystautas" <se...@lokitech.com>
Sent: Thursday, March 22, 2001 5:39 AM


>
> Great overview Harmeet.  With the way you described it, I think (2) is the
> best as well.  I think it will more easily
> a) allow people to plug in new functionality or handle things like
blocking
> by IP address or invalid senders or size limits during the SMTP
> communication.
> b) support IMAP... IMAP is a really complex protocol with problems like
> support for concurrent command processing, aside from the extensive list
of
> commands.
>
> Anyway, sounds great!  It's great to see everyone really improving James,
> and I hope to get time some day soon to help out again.

Thanks it is good to contribute to James.

I think 2 is good, my personal choice though too verbose was to have
something like.
private boolean parseCommand(String commandRaw) {
    // capture all the parameters needed to process a command
    Params params = ParamsFactory.createParams(commandRaw);
    // from the params, it should be possible to determine the Command
Executer
    Executer exec = CommandFactory.createExecuter(params);
    // now go process the command.
    exec.execute();
    return exec.keepConnectionOpen();
}

This kind of approach could have made it easier to plugin new functionality,
but I think 2 is good. It make things easy to read without adding
complexity. It is also a very incremental step, and makes it easier to find
and make more improvements if need be.

Attaching the changed SingleThreadedConnectionHandler.java for IMAP. It
roughly follows the same pattern.
The code looks a bit like
--------------------------
if state == PQR_STATE:
  if command ==  'foo':
     doFOO_PQR(...)
  else if command == 'bsr':
     doBAR_PQR(...)

else state == ABC_STATE:
   if command == 'hoo':
     doHOO_ABC(...)
   else if command == 'boo':
     doBOO_ABC(...)
-----------------------

The methods are smaller and could be factored further. A lot of methods have
very similar error handling, so can be factored some more, to reduce size
and increase readability.

Harmeet

Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Serge Knystautas <se...@lokitech.com>.
----- Original Message -----
From: "Harmeet Bedi" <hb...@yahoo.com>


> SMTPSession
> I had felt that states could be captured in multiple objects. For example
in
> FTP could have an authentication state object and RNFR, RNTO object.
> Multiple state object, could help manange intricate state machines.Either
> way capturing state information in a separate object(s) is helpful.
>
> [..]
> >
> > However I do like (2) ;)
>
> I like 2 too. If no one has an objection I will convert (1) to (2) where

Great overview Harmeet.  With the way you described it, I think (2) is the
best as well.  I think it will more easily
a) allow people to plug in new functionality or handle things like blocking
by IP address or invalid senders or size limits during the SMTP
communication.
b) support IMAP... IMAP is a really complex protocol with problems like
support for concurrent command processing, aside from the extensive list of
commands.

Anyway, sounds great!  It's great to see everyone really improving James,
and I hope to get time some day soon to help out again.

Serge Knystautas
Loki Technologies
http://www.lokitech.com/


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
----- Original Message -----
From: "Charles Benett" <Ch...@benett1.demon.co.uk>
Sent: Thursday, March 22, 2001 3:43 AM


> I've added these as SMTPHandlerNew and POP3HandlerNew as I have not had
> time to test them. In fact, as these are quite major changes, I'd prefer
> a few people to test them.

Did more testing. Hopefully others have done some too in the last few days.
If there are some problems, I will try to jump on them.

Moved
SMTPHandler and POP3Handler from proposal area to main area.
Added the SingleThreadedConnectionHandler.java for IMAP to the propsal Area.
This one I have not tested, just refactored.

Harmeet


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
> I've added these as SMTPHandlerNew and POP3HandlerNew as I have not had
> time to test them. In fact, as these are quite major changes, I'd prefer
> a few people to test them.

Thanks adding and moving to proposals, good idea about the tests.
>
> Also:
> 1) we need to combine the MessageSize limits from SizeLimitedSMTPHandler
> and add tests so that message.size() is only called if a message limit
> is set. I had a look yesturday, but I'm not sure I got it working,
> partly because...
> 2) The logging had gone squewy. The logging from SMTPHandler and
> POP3Handler should go to a logical channel SMTPServer and POP3Server and
> thence, by default, to separate log files. At the moment they are all
> getting sent to james.connections so you can't separate them.
> 3) It would be useful to performance test the new and old handlers. We
> might also look at doCommand(String[] args), I seem to recall that
> method calls with 3 params are significantly slower than with one or
> two.


I will prob. add some tests over the next few days,  plan to profile and
find potential bottlenecks in the Handlers. Not sure when...
Do you have a link on the 2+ param problem. That seems to be odd, I'd love
to learn more about it.

Harmeet



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Charles Benett <Ch...@benett1.demon.co.uk>.
I've added these as SMTPHandlerNew and POP3HandlerNew as I have not had
time to test them. In fact, as these are quite major changes, I'd prefer
a few people to test them.

Also:
1) we need to combine the MessageSize limits from SizeLimitedSMTPHandler
and add tests so that message.size() is only called if a message limit
is set. I had a look yesturday, but I'm not sure I got it working,
partly because...
2) The logging had gone squewy. The logging from SMTPHandler and
POP3Handler should go to a logical channel SMTPServer and POP3Server and
thence, by default, to separate log files. At the moment they are all
getting sent to james.connections so you can't separate them.
3) It would be useful to performance test the new and old handlers. We
might also look at doCommand(String[] args), I seem to recall that
method calls with 3 params are significantly slower than with one or
two.

Charles



Harmeet Bedi wrote:
> 
> Converted from pattern (1) to (2) for SMTPHandler and POP3Handler. Tested
> the changes.
> Here are the new converted and tested SMTPHandler and POP3Handler. I am a
> new committer but don't have appropriate checkin id(waiting on it). If
> someone could check this in, it would be great, otherwise I'll do soon.
> 
> thanks,
> Harmeet
> 
> ----- Original Message -----
> From: "Harmeet Bedi" <hb...@yahoo.com>
> Sent: Wednesday, March 21, 2001 10:16 PM
> 
> If no one has an objection I will convert (1) to (2) where
> 
> 1.
> All the code lies in a single switch statement.
> The code pattern is
> if method == 'foo':
>    do something, read input, alter state, write output
>  else if method == 'bar':
>    do something, read input, alter state, write output
>  else if method == 'shoo':
>    do something, read input, alter state, write output
>  else if method == 'boo':
>    do something, read input, alter state, write output
>  else
>    unknown state, write error message
>  Examples are: POP3Handler, SMTPHandler in James.
> 
>  2.
>  The execution code for each method is in a separate function.
>  The code pattern is
>  if method == 'foo':
>    doFoo(..)
>  else if method == 'bar':
>    doBar(..)
>  else if method == 'shoo':
>    doShoo(..)
>  else if method == 'boo':
>    doBoo(..)
>  else
>     doUnknownCommand()
> 
>   ------------------------------------------------------------------------
>                        Name: SMTPHandler.java
>    SMTPHandler.java    Type: JavaScript Program (application/x-javascript)
>                    Encoding: quoted-printable
> 
>                        Name: POP3Handler.java
>    POP3Handler.java    Type: JavaScript Program (application/x-javascript)
>                    Encoding: quoted-printable
> 
>    Part 1.4Type: Plain Text (text/plain)

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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
Converted from pattern (1) to (2) for SMTPHandler and POP3Handler. Tested
the changes.
Here are the new converted and tested SMTPHandler and POP3Handler. I am a
new committer but don't have appropriate checkin id(waiting on it). If
someone could check this in, it would be great, otherwise I'll do soon.

thanks,
Harmeet


----- Original Message -----
From: "Harmeet Bedi" <hb...@yahoo.com>
Sent: Wednesday, March 21, 2001 10:16 PM

If no one has an objection I will convert (1) to (2) where

1.
All the code lies in a single switch statement.
The code pattern is
if method == 'foo':
   do something, read input, alter state, write output
 else if method == 'bar':
   do something, read input, alter state, write output
 else if method == 'shoo':
   do something, read input, alter state, write output
 else if method == 'boo':
   do something, read input, alter state, write output
 else
   unknown state, write error message
 Examples are: POP3Handler, SMTPHandler in James.

 2.
 The execution code for each method is in a separate function.
 The code pattern is
 if method == 'foo':
   doFoo(..)
 else if method == 'bar':
   doBar(..)
 else if method == 'shoo':
   doShoo(..)
 else if method == 'boo':
   doBoo(..)
 else
    doUnknownCommand()


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Harmeet Bedi <hb...@yahoo.com>.
----- Original Message -----
From: "Peter Donald" <do...@apache.org>
Sent: Wednesday, March 21, 2001 9:41 PM
Subject: Re: method execution in protocol handlers and alternative ideas on
method processing


> At 09:19  21/3/01 -0800, Harmeet Bedi wrote:
> >Most portocol handlers have some state and methods. This could be simple
as
> >in SMTP(few methods, and connection state) or HTTP to more complicated
> >protocols like FTP(many state objects and more than a dozen methods with
> >variations).
>
> nice overview and that is mostly how I see it aswell. So far I have
written
> three servers (NNTP, SMTP+POP and FTP) and notice another design pattern
> that you may want to incorporate.
> Currently all the handlers store the state in variables and currently all
> the handlers do their own interpretation of stream inside the handler. The
> way I separated it out was like
>
> SMTPHandler, SMTPStream, SMTPSession, SMTPController
>
> SMTPSession held all the state variables with standard bean set/get
accessors.
>
> SMTPStream did all the parsing (ie separate lines into verbs and
parameters
> etc).
>
> SMTPController was the interface for the "controller" ie would determine
> whether mail is accepted (ie it may relay based on IP, username or
address).
>
> SMTPHandler was considerably more simpler. It's main loop was something
like
>


I built production FTP and LDAP Servers, played around prototyped SMTP, NNTP
and HTTP Servers.

SMTPStream
I think a custom stream for parsing input and potentially output is a good
idea.

SMTPSession
I had felt that states could be captured in multiple objects. For example in
FTP could have an authentication state object and RNFR, RNTO object.
Multiple state object, could help manange intricate state machines.Either
way capturing state information in a separate object(s) is helpful.

SMTPController
this seems interesting and useful, it sounds a bit like interceptors in
Tomcat. Did I get the analogue right ?

> Another thing I found was that method (3) and using reflection in any form
> was way to resource intensive. (Reflection is slooooow).

Another problem with reflection is that  reflection exceptions need to be
caught (they are checked exception) and the underlying exception unwrapped.

>
> However I do like (2) ;)

I like 2 too. If no one has an objection I will convert (1) to (2) where

1.
All the code lies in a single switch statement.
The code pattern is
if method == 'foo':
  do something, read input, alter state, write output
else if method == 'bar':
  do something, read input, alter state, write output
else if method == 'shoo':
  do something, read input, alter state, write output
else if method == 'boo':
  do something, read input, alter state, write output
else
  unknown state, write error message
Examples are: POP3Handler, SMTPHandler in James.

2.
The execution code for each method is in a separate function.
The code pattern is
if method == 'foo':
  doFoo(..)
else if method == 'bar':
  doBar(..)
else if method == 'shoo':
  doShoo(..)
else if method == 'boo':
  doBoo(..)
else
   doUnknownCommand()

Harmeet


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


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


Re: method execution in protocol handlers and alternative ideas on method processing

Posted by Peter Donald <do...@apache.org>.
At 09:19  21/3/01 -0800, Harmeet Bedi wrote:
>Most portocol handlers have some state and methods. This could be simple as
>in SMTP(few methods, and connection state) or HTTP to more complicated
>protocols like FTP(many state objects and more than a dozen methods with
>variations).

nice overview and that is mostly how I see it aswell. So far I have written
three servers (NNTP, SMTP+POP and FTP) and notice another design pattern
that you may want to incorporate.

Currently all the handlers store the state in variables and currently all
the handlers do their own interpretation of stream inside the handler. The
way I separated it out was like

SMTPHandler, SMTPStream, SMTPSession, SMTPController

SMTPSession held all the state variables with standard bean set/get accessors.

SMTPStream did all the parsing (ie separate lines into verbs and parameters
etc).

SMTPController was the interface for the "controller" ie would determine
whether mail is accepted (ie it may relay based on IP, username or address).

SMTPHandler was considerably more simpler. It's main loop was something like

while( SMTPSession.PREGREET == session.getState() )
{
  stream.receiveRequest();
  handlePregreetRequest( stream.getVerb(), stream.getHandler() );
}

while( SMTPSession.COMPLETE != session.getState() )
{
  stream.receiveRequest();
  handleRequest( stream.getVerb(), stream.getHandler() );
}
....

handlePregreetRequest of course would only check for the verbs that are
valid in it's particular state. This drastically decreased the amount of
complex code written and made it much easier to maintain proper state.

Another thing I found was that method (3) and using reflection in any form
was way to resource intensive. (Reflection is slooooow).

However I do like (2) ;)


Cheers,

Pete

*-----------------------------------------------------*
| "Faced with the choice between changing one's mind, |
| and proving that there is no need to do so - almost |
| everyone gets busy on the proof."                   |
|              - John Kenneth Galbraith               |
*-----------------------------------------------------*


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