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/