Hi Eugen,

> Quite a long email :) .

Hehehe, yes. Good thing I stopped when I did. Glad it got some dialogue going. 
I very much appreciate your reply.

Just a few comments inline.


> I believe the protocols share the protocols-api beacuse they are
> all/mostly all line based protocols.
> 
> Like you, I do think this is not a good solution, we should use
> composition instead of inheritance.

Ok, glad to know I’m not alone.


> I believe each protocol is independent and should build to an
> independent server (SMTP, IMAP, POP3, JMAP) .

I’m glad you think so, too.



> We could compose these independent servers into a single running process
> since they share the same language and platform (Java).

From a “beginner’s” perspective (which I still am), that makes a whole lotta 
sense, and corresponds well with how I think a system ought to be built.



> I do believe some duplication is better than coupling (this also applies
> to dependency management).

Again, glad to know I am not alone.



> Regarding ProtocolHandlerChain, the API is driven by how Netty
> implements protocols so please read a bit about that
> https://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-4 .

Let me just repeat what you wrote: “the API is driven by how Netty implements 
protocols”.

That is just craziness to me. An API should never be driven by an 
implementation, pretty much by definition. It is always the implementation that 
should, well, implement the API. I think that writing the API because Netty 
works a certain way is completely backwards.

Now, if you are saying that the API is “inspired by” Netty, then perhaps I 
could buy that. However, that seems to be really limiting the API. It should be 
possible to have different implementations of an API, but by including 
lower-level concepts it cuts off a lot of potential solutions.

The API should be as stable as possible, and still valid even if somebody finds 
a better way of implementing it. All other components should depend solely on 
the API (not the implementations), and the runtime system is built by composing 
the different implementations.

From the sounds of it, that is what you want to move towards, so it sounds like 
we’re on the same page.

Using Netty in the implementation because it is fast (or whatever) makes 
perfect sense, so nothing against Netty or adapting to how Netty works, but I 
think this again mixes the roles of API and implementation.



> I don't believe the code is super clean but it does work and is quite
> efficient and fast.

Yes, that is important, but again, this comment about being “efficient and 
fast” seems perfectly valid for an implementation, but not really for an API. 
The API should be more about expressing the model and drawing clear component 
boundaries. (It should not preclude a good implementation, of course, but 
should usually not force a particular implementation either.)



> I agree with the coupling and it is going to take some effort to go
> through all of the modules and clean them up.

Since I am pretty much stuck with the documentation efforts (as I have 
mentioned I need more input from the community if I am to move forward), what I 
think I’ll try to do next is write an “independent” API for SMTP. My hope is 
that this will:

 * Provide an example as to how to write a “clean” and independent API
 * Help with documentation (because in a way, the API **is** the documentation 
because it should reflect the model very well)
 * Continue to use the “existing” code that “does work and is quite efficient 
and fast” to implement the new API

In the worst case we can throw it away, in the best case it will provide an 
example of how to move forward with better componentization of James.


Cheers,
=David


Attachment: signature.asc
Description: Message signed with OpenPGP

Reply via email to