On Feb 29, 2008, at 2:55 PM, Mike Heath wrote:

Alan D. Cabrera wrote:

So, HCF can be optional.  If you create HCs directly any cookies that
are created are scoped w/ that client.  The HCF would take an
implementation of a CookieManager (CM) interface. I guess HC could as
well.

That's how I've designed my API. The HCF has a configure CM and the HC
can have it's own CM if that's desired.

I don't have explicit support for CookieManager chaining though.  I'll
have to add that.

What is CM chaining?

I see similarities w/ what Mike has proposed; geniuses think alike. :)
So here are the issues with what I have with that design.  Most are
probably bike shed issues.

- The hierarchy is a bit confusing.  HttpConnector and HttpClient
inherit off of HttpClientConfigurable but, HttpConnector can generate
HttpClients; seems odd to me in that it appears to be mixing metaphors.

The idea that I'm trying to convey here is that the HCF (or
HttpConnector in the case of my API) can hold a configuration that will
be the default configuration of the HCs the HCF creates.

Ok, so I guess the cause of the confusion for me would be that HttpConnector can generate HttpClients and HttpConnecttions. We discuss this below.

- I think that HttpClientFactory and HttpClient seems more concrete than HttpConnector and HttpClient/HttpConnection. The relationship seems a
bit obtuse until one reads the javadocs and thinks on it a bit.  I
suggest that we split your metaphor and have a
HttpClientFactory/HttpClient and HttpConnectionFactory/ HttpConnection.
I really doubt that someone will be generating *both* connections and
clients at the same time. The factories would extend HttpFactory which would be like HttpClientConfigurable but without a lot of the parameters like user agent. I really like name factory, it's an industry accepted
pattern.  Implementations of the factories would have getters/setters
for timeouts and what ever the factory implementer thought was cool,
e.g. pooling mumbo jumbo.

I have to agree that I like the name HttpClientFactory too.  I keep
going back and forth on it though. I went with HttpConnector in my API
because it's what would hold the MINA IoConnector instance and because
it's creating both HttpConnections and HttpClients.

The reason that I have HttpConnector creating both HttpClient and
HttpConnections is because I was thinking that the HC implementation
would just use an HttpConnection under the hood.  This way we could
create a generic HttpClient implementation that would just use a
HttpConnection.  We could also create a generic HttpConnection pooler
that simply pool HttpConnection instances. This way we would only have
to implement different HCF and HttpConnection instances to support
different transports.  This should make it easier for us to support
different versions of MINA as well as make room for non MINA based
implementations.  Of course, why would anyone NOT want to use MINA? ;)

As I think about it though, there's still no reason we can't separate
the HttpClientFactory and the HttpConnectionFactory and still do what I
just described. :)

Yeah, I think that while we probably will have an HTTPConnection under the hood of an HTTPClient, there's no reason to stress that implementation detail by having a connector generate both. I think we should ask how does that strengthen the metaphor? I think it detracts. When we split the two we get two nice clean and easy metaphors for users to swallow.

We would only merge the two if it were commonplace for one to use both to accomplish a single task; a situation that I am stretched to contrive.

- HttpConnection, I don't see the point in setting an attribute w/ out a
value just to emulate a boolean.  I'm sure that I'm being dense but I
think it's important to keep it crazy simple.
- setAttributeIfAbsent can be implemented by locking on the connection,
no?  I'm probably being dense here too.

All the attribute methods were copied verbatim from MINA's IoSession.

From an implementation perspective, using an attribute w/o a value to
emulate a boolean keeps things crazy simple IMO. If I need a flag I can
easily see if the flag is set by calling containsAttribute.  I don't
have to do something like
((Boolean)connection.getAttribute(key)).booleanvalue().  We use this
patter in MINA frequently. It seams to work fine and is well understood
by MINA users.

There's great merit in sticking w/ MINA's paradigm even if, IMO, this bit is flawed.

I am not against checking to see if a key exists. I'm against setting a key w/ no value which, IMO, smacks of an ad hoc addition. But, in this case my opinion is moot and, like I said, a bike shed issue.

Synchronizing on the HttpConnection would only work of all the attribute methods were synchronized which we don't guarantee. That is why we have
setAttributeIfAbsent.  Besides, if you're using a ConcurrentMap to
implement the attribute support, you'll want to be able to use
ConcurrentMap#putIfAbsent().

The default implementation should sync on this. Exotic implementations would use the IoSessionDataStructureFactory and can make the appropriate wrapper. I think that it smacks of an ad hoc addition; JMHO. I think that there is great value in following the paradigms that maps in Java use, i.e. wrap behavior. But, in this additional case my opinion is moot and another bike shed issue.

Thoughts?

Thanks for the feedback! I'm really excited to move forward with this.
I've had a number of discussions with people outside of Apache WRT
building an asynchronous web services client framework.  The people I
spoke to are specifically very interested in an asynchronous Amazon Web
Services client.

Yeah, I'm writing a Xen API JCA Connector and want to use this puppy, among other things.


Regards,
Alan

Reply via email to