Limited Invalidation

Summary

Provide an additional mechanism for gadget developers to control the lifecycle of specific HTTP content cached by OpenSocial containers beyond what is already available through standard HTTP cache control headers. This proposal allows developers to explicitly invalidate the following content

  • Content the container has fetched on behalf of a user including proxied renders and authenticated/signed makeRequest calls while using a gadget
  • URLs for gadget specs, gadget manifests & message bundles

This specification does not attempt to provide a generalized solution for managing the lifecycle of static resources like images for which a container may be providing edge-caching facilities to developers. This solution only addresses the need to invalidate content that immediately impacts content served to the end user as part of either a gadget render request or authenticated call. URL versioning adequately provides for invalidating static resources, is already under direct developer control and has immediate end-to-end effect.

Also its worth noting that this solution does not provide the ability to invalidate content for all users of an application at once as developers can achieve this effect by versioning the URLs of the addressed content.

Discussion Thread

Spec Updated

Benefits

This API allows developers to minimize the number of requests made to their backends while maintaining an entirely consistent user experience.

  • Developers can set very long HTTP expirations on content they serve and only invalidate it when they know it has changed, typically in response to user interaction. This allows developers to switch from serving content once per gadget render to once per data change which should represent a significant reduction in traffic and the costs associated with serving it.
  • Containers can serve invalidated content even if the developer backend is unavailable. This allows applications to have higher apparent availability.

REST/RPC

Containers MUST support the invalidation endpoint even if they do not perform any caching and MUST provide an entry for it in their XRDS

  <XRDS xmlns="xri://$xrds">
      <XRD xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" xmlns:os="http://ns.opensocial.org/2008/opensocial" version="2.0">
            ....
            <Type>http://ns.opensocial.org/2008/opensocial/invalidate</Type>
            <os:URI-Template>http://api.example.org/invalidate</os:URI-Template>
          </Service>
      </XRD>
  </XRDS>

To invalidate content a developers backend notifies the container of the content it wishes to invalidate by making a 2-legged OAuth call to the REST/RPC endpoint with one or many keys to be invalidated. The consumer key in the 2-legged OAuth call is used by the container to identify the calling application. Keys have the following general form

  
  <invalidation-key> = url | <opensocial id>

When invalidating opensocial id's containers MUST support invalidating both fully qualified opensocial ids of the form "<domain>:<domain relative id>" as well as ids of the form "<domain relative id>".

Each request accepts a repeated group of ids, in JSON the format is

  { invalidationKeys : [ invalidation-key, invalidation-key, ...] } 

and in XML

  <invalidationKeys>
     <invalidationKey>...</invalidationKey>
     <invalidationKey>...</invalidationKey>
  </invalidationKeys >

An application can execute an invalidation request as a POST to the REST endpoint described in the containers XRDS or as a JSON-RPC call. Response codes have the following meanings

  • 200 - Success, all invalidations processed successfully.
  • 403 - Forbidden because authentication failed.
  • 409 - The request was partially processed, the set of invalidation keys that were not honored MUST be included in the response body in the format the request was made.

Containers MAY reject invalidation requests for policy reasons.
Containers MAY continue to serve content that has already been invalidated until the container is able to successfully fetch a replacement from it original source.

Examples

Invalidate the gadget spec and message bundle of an application using REST

  POST /api/rest/invalidate
  HOST opensocial.example.org
  Content-Type application/json
  {
     invalidationKeys : [ "http:--www.myapp.com-gadgetpec.xml",--www.myapp.com-messagebundle.xml"]
  }

Invalidate content for a set of users using JSON-RPC

  POST /api/rpc
  HOST opensocial.example.org
  Content-Type application/json
  {
     method : "invalidate.post",
     params : {
       invalidationKeys : [ "example.org:12345",4567", "3456778"]
     }
  }

JS API

The opensocial JS API will expose the following interface to running gadgets to allow them to invalidate content.

 opensocial.invalidate([invalidation key, invalidation key, ...])

Containers MUST allow invalidation of content for users other than just the viewer/owner of the running gadget.