On Mon, Oct 01, 2001 at 10:13:16PM -0700, Ian Holsman wrote:
> has anyone got a list of things that they want the client to do?

Sander posted a short list in the initial proposal, which was a good
snapshot of a discussion between the two of us the other night.

> we could use this as a 'STATUS/Wish' list.

I added a docs/ directory, but am pending on checking in a roadmap.txt until
we get the apr-serf repository added into avail. I'll dig up Sander's email
and add those, too.

For now, it is just a random set of notes, but it can be refined as we reach
consensus here.

>...
> * Simple 'GET/Post/Head' function just does it and returns
>    the contents in a bucket-brigade

Right.

I would suggest familiarizing yourself with the Neon API. In particular,
this point is similar to the functions in ne_basic.h

> * Async version of above.. (like LWP::Parallel) I just push
>    GET requests and it notifies me when there is an event for
>    one of them.

In the proposal, we discussed the notion that you can do a push/pull on each
side of the request/response sequence. In your scenario above, the API would
contain an API such as "serf_process(ctx)" which enters into a select/poll
loop to deliver any pending requests, and then to call back to the client
when responses arrive.

The API should be thread capable so that serf_process() and its callbacks
can execute on a thread (while, say, another thread is pushing requests).

Another approach to handling requests is the synchronous ("pull") fashion:

    brigade = serf_get(connection, url, ...)

The above would synchronously push the request, then wait for the response
to arrive. Note that pipelining requests is still possible in the pull
model:

    serf_send_request(connection, "GET", url1, ...)
    serf_send_request(connection, "GET", url2, ...)
    serf_send_request(connection, "GET", url3, ...)
    bb1 = serf_get_response(connection, ...)
    bb2 = serf_get_response(connection, ...)
    bb3 = serf_get_response(connection, ...)

(I use ... because I'm not sure what all args might also be needed)

Requests can also be push/pull:

pull:
    serf_note_request(connection, my_callback)
    serf_process(ctx)

push:
    serf_send_request(connection, ...)
    serf_process(ctx)

> * filters used for 'serf' as similiar in syntax/use to HTTPD

They come in two directions: push and pull. Push is like the output stack in
httpd (data is pushed through the stack). Pull is like the input stack --
data is pulled up thru the stack.

I believe that we can architect all filters as push filters. If we want to
use them in a pull fashion, then we can do something like:

  defined stack: network <-> F1 <-> F2 <-> app

  serf_get_brigade()
  {
      /* network */
      brigade = read_socket()
      
      /* F1 and F2 chain */
      temp_chain = F1
      temp_chain->next = F2
      temp_chain->next->next = gatherer
      pass_brigade(temp_chain, brigade)

      return gatherer->collected
  }

We're essentially "pushing" the data up the stack and collecting the
resulting brigade in a "gatherer" filter. The collected brigade is then
returned from the get_brigade function.

Since all filters are written as a push filter, and they can be used in both
directions, then we don't have httpd's dual model for coding filters,
meaning that we don't have to have to implementations of a chunk or dechunk
filter.

> * HTTP/1.1 Support

IMO, we *only* deliver HTTP/1.1 requests. I don't believe there is any
reason for us to ever send a 1.0 request.

We must support HTTP/1.0 and HTTP/1.1 responses, though. It could be argued
that we need to support HTTP/0.9 responses, but I'd say "screw that"

[ an app can never know if a target server requires an HTTP/1.0 request; if
  we presume that the app *does* know, and can call a function to set the
  use of the HTTP/1.0 protocol, then it should just be coded to call a
  different library. ]

> * SSL Support

Absolutely.

> * Connection Pooling per server (ie we keep a max of n open connections
>    to a server and we re-use these on different requests)

Hmm. Possibly. I can certainly see the utility of this.

> * send requests to a server from a list of servers/ports (via round-robin)

This is just part of the pooling -- the connection pool can use a full list
of server/ports for its connections. Ideally, we could just use the linked
list of apr_sockaddr_t structures returned from apr_sockaddr_info_get().

Cheers,
-g

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

Reply via email to