On Tue, 28 Oct 2003, Robert Collins wrote:
> I think we would benefit from a extension to the store client interface,
> to support notification of new data arriving (as opposed to the
> completion of read requests). This would be used for:
> 1) multipart responses in the future, where the order of offset-length
> data isn't predictable.
This I don't quite get how this would help.. at least not without
additional concepts. If doing this then there needs to be a somewhat
bigger scope considered. See below for some discussion on what I think
about Range processing how/when/why.
> 2) passing through range responses where the range processing fail for
> whatever reason.
This I do not get at all..
Range processing of incoming data (merging of partial responses etc) needs
to be done in the HTTP server side. The client side should not need to
care about this, and neither should the store (at least not initially).
Range reply generation should be done at the client side, asking the store
for the data it needs. This requires a conditional open API call where the
store client can ask if the requested ranges are available in the cache,
and if we want to support non-linear ranges then the API needs to support
some kind of random reads. But hold that thought about random reads a
little (there is additional complications).
If not all requested data is available in the cache then my opinion is
that the request should be a handled as a cache miss and processed by the
server side code.
In neither case should the store need to know the details of HTTP range
processing. All the store needs to know is that a object consists of
* metadata used by the store
* a header portion
* a body, possibly sparse
The API for both reading and writing from the store needs to reflect this,
and handle reading/writing of the body in arbitrary order.
The servers side, when merging partial responses, need to be able to ask
the store in detail on what we have in the cache allowing it to construct
the proper ranged request to fill in the blanks where required.
Merging of partial responses should (at least until we have a middle
layer, allowing forwarding between server/client without using the store)
be done into a new store object. This is important to guarantee
consistency and a clean path, and avoids a very sticky web of issues if
there is multiple clients asking for the same object etc. The drawback is
that we will loose caching of "concurrent" ranges from different requests
(i.e. due to download accelerators etc).
From this I propose the following store client API guidelines:
* header and body data handled separately, not as a single stream.
* when a store client is initiated it must indicate if a ranged/partial
response is acceptable, and in such case what ranges it wants.
* the store then gives the client the entity header
* followed by ranges of body content. The ranges of body content should
preferably be returned in the same order as asked for when the store
client is initiated (SHOULD on cache hits, MAY on cache misses while using
the store for forwarding of data)
Lets dive into a few examples here to better illustrate the requirements:
[based on forwarding via the store design]
** Full object cached. Range request received. **
A store client is initiated, asking for the required ranges.
The store then returns the ranged body data in the order requested.
If there then is a problem reading in some of the content from the store
then this should be handled as any read error.
** No object cached. Range request received **
Cache miss. Request forwarded.
Server-side stores the header component, and then the reply body ranges as
received.
Client-side gets the ranges as stored by the server-side, and transforms
this back into a suitable HTTP reply.
** Partial object cached. Normal request **
Partial cache miss. Request forwarded but with a reference to the partial
object given to server-side.
Server-side constructs a suitable Range request to fill in the blanks and
then forwards this request. To build the Range request a store client is
initiated to the old object indicating a partial response is acceptable
and what ranges is wanted. The store must in return indicate what of the
wanted ranges are available (or not).
When the reply headers are received these are stored into the new object
(as headers).
Then body content is stored into the new object by alternating copying
from the old object and reading from the reply to try to build a linear
object.
In the special case that the reply contains reordered ranges in a
different order than requested the client-side store client may need to
wait until the requested content is available while other content is read
from the reply, but this should not normally happen unless the contacted
server is buggy.
In the other special case where it is determined after receiving the reply
headers it is not safe to merge the two replies, the reply is discarded
and the request re-forwarded as a non-ranged request.
** Partial object cached. Ranged request for available ranges **
Cache hit. Handled as in the case where the full object is cached.
** Partial object cached. Ranged request where not all is available **
Handled more or less as the "Partial object cached. Normal request" case,
except that the requested ranges is taken into account when constructing
the Range request.
Ideally the request forwarding chain should be redone before doing all
this to separate the store from the forwarding path by using a forwarding
layer acting as a broker between client/server/store layers, with the hot
object cache acting as a memory cache between the broker and the store.
client side <--> forwarding layer/broker <--> server side
^
|
v
hot object cache
^
|
v
store
this would simplify several of these issues, and allow for considerably
more efficient operation (especially when merging partial responses).
Regards
Henrik
Received on Wed Oct 29 2003 - 16:44:27 MST
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:20:44 MST