So Sander and I were chatting about connection pools, per Ian's mail about
them. I think there are a few key data elements in the API:

        Context (*)
          / | \
    Session Pools/Groups
          / | \
        Sessions
            |
       Connections

In this diagram, we have a high level context for all operations. Within
that, there are multiple Session pools/groups. To avoid terminology clash,
we might want to refer to these as "session groups".

A session group is simply a collection of individual sessions. Each group
represents a *logical* server. Any of the sessions could be used to invoke a
given request. The multiple sessions could arise through three mechanisms:

1) the app says "open two connections to that server"

2) DNS for a server returns multiple IPs (*and* the app wants multiple
   connections)
   [ possibly, we would keep all the IPs and try them in sequence; so there
     would multiple *possible* sessions, but we'd only use one at a time ]

3) the app manually adds sessions to a group because it knows that
   www1.example.com and www2.example.com are the "same"

The session group satisfies connection pooling and multiple IP returns for a
hostname.

Each session represents a logical connection to the server. Because of
timeouts, the server closing the pipe, or whatever, the session spans
connections. But a given session will only ever open one connection at a
given time.

Note that the API wouldn't really expose the connection. That is really just
a darn socket. The app *may* need to see individual sessions, but I don't
think so. The group is really the *logical* server.

Hmm. I was about to say that an app might need to say "well, this session
should use <these> credentials, and that session should use <those>." Or
maybe distinct cookies or whatever. But no! The app should use separate
session groups for those.

IOW, we could state that a session group is really the public API (and maybe
simplify the terminology exposed? just call it a session in the API and call
the other things sub-sessions or connections or whatever?)

Each session group would have the various session-level bits attached to it:
credentials, group-size, proxy setting, etc.

At the top level is the serf context. It contains the list of all the
groups. More importantly, it is the level where the select() occurs. You can
process request/response cycles in various ways:

1a) synchronously send requests
1b) serf_process(ctx) sees a socket is available for reading and a request
    is pending, so it pulls the new request from the app

2a) synchronously read responses from each session (or "sub-session"; maybe
    for this type of reading, we need to expose the session concept in
    addition to the session groups)
2b) serf_process(ctx) sees a socket has data on it, so it reads it, matches
    it with the appropriate request/response pair and shoves the data down
    an input stack.

The context could also contain the SSL session IDs that Daniel just
mentioned in his post. Dunno; they might make more sense at the group level.

(*) "context" is a horrible word for this. It is just too generic.
Suggestions welcome. Maybe it won't be too bad as long as we keep calling it
a "serf context" (serf_ctx_t) or something to keep it more specific.


Now... there is definitely the separate task of simplified functions to
reduce the full architecture down to "shut up. just get me <this> file." All
well and fine, but the base architecture is needed first :-)

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Reply via email to