Subject: [core] Caching of responses

From: Klaus Hartke <[email-masked]>
Date: Tue, 16 Nov 2010 18:13:53 +0100

A cacheable response contains one or or more of the following information:

* Transaction-local information
    - Token
    - Block
    - Subscription lifetime

* URI
    - Uri-Authority
    - Uri-Path
    - Uri-Query

* Freshness-related information
    - Max-Age

* Entity
    - Status
    - Etag
    - Content-Type
    - Content

The semantics of response codes are currently not specified in coap-03
but implicitly imported from HTTP.

I find it confusing that a cache stores responses in whole.

- Token, Block and Subscription lifetime clearly shouldn't be cached.
- Wouldn't it make more sense to store a local expiration date (i.e.,
an absolute value) instead of Max-Age (a relative value)?
- Does a 304 response set the expiration date of the stored response
to (Now + StoredResponse.MaxAge) or (Now + 304Response.MaxAge)? (Since
Max-Age has a default value, a response cannot not have a Max-Age).
- Does a response retrieved from a cache have the original Max-Age
value or an updated Max-Age value that reflects the remaining time the
response is considered fresh?
- Is a 404 response cached? Can a stored 404 response be validated
with an Etag? Does Max-Age apply to 404 responses?
- Is any other 4xx or a 5xx response cached?

A lot of this are implementation details. But I feel that some bits
are currently underspecified and should be clarified.

Proposal:

* A cache stores tuples of the form { URI, Etag, Status, FreshBefore,
ContentType, Content }

* A cacheable response with any code except 304 adds or updates the
tuple for the given URI and Etag.
  FreshBefore is set to (Now + response.MaxAge).
  ContentType and Content are set to nil for any code except 200.
  Any previously stored tuple for the given URI is considered not fresh.

* A cacheable response with code 304 updates the tuple for the given
URI and Etag.
  FreshBefore is set to (Now + response.MaxAge).
  Status, ContentType and Content remain unchanged.
  Any previously stored tuple for the given URI is considered not fresh.

So, an Etag absent from a response is treated like an empty Etag,
except that a stored tuple with empty Etag cannot be validated, and
there is always at most one tuple that is considered fresh.

Token, Block, Subscription lifetime, Location and Max-Age options are
not cached.

Klaus

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 16 Nov 2010 19:01:34 +0100

Hi Klaus,

nice! These are all very good points for clarification of the spec.
Let me try to add my personal view of how they might be resolved.
As usual, I'll use RFC 2616 for guidance, unless that would lead down the wrong path.

> * Freshness-related information

(s/Content/Payload/...)

> I find it confusing that a cache stores responses in whole.

Does the current text say that?  Where?

> - Token, Block and Subscription lifetime clearly shouldn't be cached.

(Unless a Cache caches any blocks separately.
During a blockwise sequence of initial GETs, the Cache will have part of the resource and MAY already answer requests for the parts it has!
But yes, that is not caching the Block option, it is caching parts of the resource representation.)

> an absolute value) instead of Max-Age (a relative value)?

I would indeed expect a cache implementation to convert a max-age into an absolute expiration time.
This is an implementation detail, however.  

RFC 2616 says:
   When
   the max-age cache-control directive is present in a cached response,
   the response is stale if its current age is greater than the age
   value given (in seconds) at the time of a new request for that
   resource.

> Max-Age has a default value, a response cannot not have a Max-Age).

Good point.  The second.

RFC 2616 says:
   If a cache uses a received 304 response to update a cache entry, the
   cache MUST update the entry to reflect any new field values given in
   the response.

> response is considered fresh?

The latter.

> with an Etag? Does Max-Age apply to 404 responses?

HTTP does allow the caching of errors.

> - Is any other 4xx or a 5xx response cached?

HTTP does allow the caching of errors.
(Of course, it never mandates caching.)

> * A cache stores tuples of the form { URI, Etag, Status, FreshBefore,

This is getting dangerously close to an implementation model.

One other interesting question is what happens to elective options not understood by the cache.

>  FreshBefore is set to (Now + response.MaxAge).

Again, that is an implementation detail.  The Cache might as well cache max-age and keep a local age counting up as in the model used by RFC 2616.
This is equivalent to FreshBefore but does not introduce a separate concept.

> Token, Block, Subscription lifetime, Location and Max-Age options are

(See above for max-age.)

I don't like the sentence in 5.1:
   If the client specifies a Max-Age of zero seconds, then the response
   MUST discard the cached representation and return a fresh
   representation.

"Discard"?  Of course, it should be able to serve the cached representation to others that request less critical max-age values until the new response is available.

Gruesse, Carsten