You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Bruce Godden <br...@oerc.ox.ac.uk> on 2009/12/22 12:57:24 UTC

Caching of makeRequest data

Hi,

I am working on a set of gadgets which use some shared data which is fetched using gadgets.io.makeRequest. I am using pubsub to pass messages between gadgets to tell them that they need to fetch new data. My problem is that Shindig is caching the data and so when it is refetched the old data is fetched again instead of the new data. I can work around this by avoiding caching (mostly) by setting the REFRESH_INTERVAL makeRequest parameter to a small number like 1 (or other more severe cache busting tricks) but I would actually like the data to be cached. Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?

By the way, what is supposed to be the effect of setting REFRESH_INTERVAL to 0? My experience seems to show that it actually allows the data to be cached for a significant time rather than disallowing it completely. Is this expected?

Bruce Godden
Oxford e-Research Centre


RE: Caching of makeRequest data

Posted by "Ciancetta, Jesse E." <jc...@mitre.org>.
I ended up digging into this further to try to get a REFRESH_INTERVAL value of 0 working and found that I needed to change the core.io JavaScript to do it.

When you execute a makeRequest using GET for the method, and either no REFRESH_INTERVAL or a REFRESH_INTERVAL with a value greater than 0, makeRequest ends up sending an XHR GET to Shindig with a "refresh" parameter with a positive value (either the default value, or the value you specified).  Shindig then uses that value for the TTL on the response in its cache (so Shindig will cache server side for the right amount of time), and also uses it to generate cache control headers that Shindig sends in the response to the XHR call (so the browser will cache client side for the right amount of time).

When you execute a makeRequest using GET for the method and pass a REFRESH_INTERVAL value of less than 1, makeRequest ends up sending an XHR POST to Shindig *without* a "refresh" parameter.  Even though the XHR to Shindig was a POST, since the method Shindig is told to use to fetch the remote content is a GET, and no "refresh" parameter was included, Shindig uses whatever cache control headers the distant server sends back to control its server side cache, but the client cache (browser) doesn't cache the response since it was sent as a POST.  So you end up in a scenario where even though you see a new XHR POST being sent to Shindig with every makeRequest executed, the response from Shindig ends up coming out of its server side cache even though you included a REFRESH_INTERVAL of 0 in the makeRequest call.

Modifying /features/core.io/io.js to add the "refresh" parameter with a value of 0 in the second scenario resolves the issue.  Does this sound like the right way to fix this?  Is this going to break anything else obvious?  If this sounds like the right solution I could open an issue on it along with a patch for the change I made.

Another interesting issue I ran into that haven't figured out how to workaround yet is when different gadgets are sending makeRequest calls for the same content but with different REFRESH_INTERVAL values...  So if gadget A asks for url XX with a REFRESH_INTERVAL of 3600 (one hour) and then gadget B also asks for url XX with a REFRESH_INTERVAL of 60 (one minute) -- the longer refresh interval wins and gadget B gets older content than it wants...  Has anyone else run into this scenario?  Is there a good solution for it?  It almost seems that instead of sending a REFRESH_INTERVAL parameter, gadgets really want to send a MAX_AGE parameter to say how stale of content they are willing to tolerate.

Thanks,

--Jesse

-----Original Message-----
From: Ciancetta, Jesse E. [mailto:jcian@mitre.org] 
Sent: Wednesday, December 23, 2009 10:07 AM
To: shindig-dev@incubator.apache.org
Subject: RE: Caching of makeRequest data

A colleague of mine happened to ask me about bypassing the cache today too so I ended up digging this a bit myself.  Here is what I found:

If you want to control caching from the client (gadget) side when using gadgets.io.makeRequest, using the gadgets.io.RequestParameters.REFRESH_INTERVAL parameter [1] appears to be the right way to do it.

However, if you're using the Shindig 1.0 release (which I am), the REFRESH_INTERVAL only half works -- it does properly control the client side (browser) cache, but it does not properly control the server side (Shindig) cache.  In Shindig 1.1 this has been fixed (at least at the HEAD of trunk -- not sure when the fix was added).

The issue is that in Shindig 1.0, the MakeRequestHandler.buildHttpRequest method [2] never does anything with the parameter that gadgets.io.makeRequest adds to the XHR going back to Shindig -- that same method in Shindig 1.1 does [3] with this code snippet:

    if (request.getParameter(REFRESH_PARAM) != null) {
      try {
        req.setCacheTtl(Integer.parseInt(request.getParameter(REFRESH_PARAM)));
      } catch (NumberFormatException nfe) {
        // Ignore
      }
    }

One thing I noticed though is that it appears, even in Shindig 1.1, the HttpResponse.getCacheExpiration method [4] (which ends up being used in the AbstractHttpCache.responseStillUsable method to determine if a cached response is still valid), in the case of a cached response that came from a makeRequest call which included the REFRESH_INTERVAL parameter, uses the timestamp from the HTTP response of the distant server in the calculation of the expiration.  I think that means that if the time is wrong on the distant server (like if it's ahead by say three hours), even if in your makeRequest you specify a REFRESH_INTERVAL of an hour, since the distant server is ahead by three hours the response would still end up being cached for four hours.

I'm guessing the timestamp is pulled from the response of the distant server in case that response itself was cached (maybe on a proxy somewhere) and your trying to honor their cache control headers -- in that case using the Shindig server time could cause issues...

So I'm wondering if, in the case of a makeRequest that comes in with a REFRESH_PARAM specified, should the Shindig server time be used as the basis of calculating cache expiration time (since what you really want to do is expire that cached response XX seconds from the Shindig servers current time, regardless of what time the distant server thinks it is)?

--Jesse
	
[1] http://wiki.opensocial.org/index.php?title=Gadgets.io_%28v0.9%29#gadgets.io.RequestParameters.REFRESH_INTERVAL
[2] http://svn.apache.org/repos/asf/incubator/shindig/branches/1.0.x-incubating/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
[3] http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
[4] http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java

-----Original Message-----
From: Chirag Shah [mailto:chiragshah1@gmail.com] 
Sent: Tuesday, December 22, 2009 1:54 PM
To: shindig-dev@incubator.apache.org
Subject: Re: Caching of makeRequest data

>Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?

If makeRequest is hitting a server under your control, you can use the
HTTP caching headers to dictate how long the response should be
cached. If you use this approach, make sure the refresh_interval
parameter is not set.

On Tue, Dec 22, 2009 at 3:57 AM, Bruce Godden
<br...@oerc.ox.ac.uk> wrote:
> Hi,
>
> I am working on a set of gadgets which use some shared data which is fetched using gadgets.io.makeRequest. I am using pubsub to pass messages between gadgets to tell them that they need to fetch new data. My problem is that Shindig is caching the data and so when it is refetched the old data is fetched again instead of the new data. I can work around this by avoiding caching (mostly) by setting the REFRESH_INTERVAL makeRequest parameter to a small number like 1 (or other more severe cache busting tricks) but I would actually like the data to be cached. Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?
>
> By the way, what is supposed to be the effect of setting REFRESH_INTERVAL to 0? My experience seems to show that it actually allows the data to be cached for a significant time rather than disallowing it completely. Is this expected?
>
> Bruce Godden
> Oxford e-Research Centre
>
>


RE: Caching of makeRequest data

Posted by "Ciancetta, Jesse E." <jc...@mitre.org>.
A colleague of mine happened to ask me about bypassing the cache today too so I ended up digging this a bit myself.  Here is what I found:

If you want to control caching from the client (gadget) side when using gadgets.io.makeRequest, using the gadgets.io.RequestParameters.REFRESH_INTERVAL parameter [1] appears to be the right way to do it.

However, if you're using the Shindig 1.0 release (which I am), the REFRESH_INTERVAL only half works -- it does properly control the client side (browser) cache, but it does not properly control the server side (Shindig) cache.  In Shindig 1.1 this has been fixed (at least at the HEAD of trunk -- not sure when the fix was added).

The issue is that in Shindig 1.0, the MakeRequestHandler.buildHttpRequest method [2] never does anything with the parameter that gadgets.io.makeRequest adds to the XHR going back to Shindig -- that same method in Shindig 1.1 does [3] with this code snippet:

    if (request.getParameter(REFRESH_PARAM) != null) {
      try {
        req.setCacheTtl(Integer.parseInt(request.getParameter(REFRESH_PARAM)));
      } catch (NumberFormatException nfe) {
        // Ignore
      }
    }

One thing I noticed though is that it appears, even in Shindig 1.1, the HttpResponse.getCacheExpiration method [4] (which ends up being used in the AbstractHttpCache.responseStillUsable method to determine if a cached response is still valid), in the case of a cached response that came from a makeRequest call which included the REFRESH_INTERVAL parameter, uses the timestamp from the HTTP response of the distant server in the calculation of the expiration.  I think that means that if the time is wrong on the distant server (like if it's ahead by say three hours), even if in your makeRequest you specify a REFRESH_INTERVAL of an hour, since the distant server is ahead by three hours the response would still end up being cached for four hours.

I'm guessing the timestamp is pulled from the response of the distant server in case that response itself was cached (maybe on a proxy somewhere) and your trying to honor their cache control headers -- in that case using the Shindig server time could cause issues...

So I'm wondering if, in the case of a makeRequest that comes in with a REFRESH_PARAM specified, should the Shindig server time be used as the basis of calculating cache expiration time (since what you really want to do is expire that cached response XX seconds from the Shindig servers current time, regardless of what time the distant server thinks it is)?

--Jesse
	
[1] http://wiki.opensocial.org/index.php?title=Gadgets.io_%28v0.9%29#gadgets.io.RequestParameters.REFRESH_INTERVAL
[2] http://svn.apache.org/repos/asf/incubator/shindig/branches/1.0.x-incubating/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
[3] http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
[4] http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java

-----Original Message-----
From: Chirag Shah [mailto:chiragshah1@gmail.com] 
Sent: Tuesday, December 22, 2009 1:54 PM
To: shindig-dev@incubator.apache.org
Subject: Re: Caching of makeRequest data

>Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?

If makeRequest is hitting a server under your control, you can use the
HTTP caching headers to dictate how long the response should be
cached. If you use this approach, make sure the refresh_interval
parameter is not set.

On Tue, Dec 22, 2009 at 3:57 AM, Bruce Godden
<br...@oerc.ox.ac.uk> wrote:
> Hi,
>
> I am working on a set of gadgets which use some shared data which is fetched using gadgets.io.makeRequest. I am using pubsub to pass messages between gadgets to tell them that they need to fetch new data. My problem is that Shindig is caching the data and so when it is refetched the old data is fetched again instead of the new data. I can work around this by avoiding caching (mostly) by setting the REFRESH_INTERVAL makeRequest parameter to a small number like 1 (or other more severe cache busting tricks) but I would actually like the data to be cached. Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?
>
> By the way, what is supposed to be the effect of setting REFRESH_INTERVAL to 0? My experience seems to show that it actually allows the data to be cached for a significant time rather than disallowing it completely. Is this expected?
>
> Bruce Godden
> Oxford e-Research Centre
>
>

Re: Caching of makeRequest data

Posted by Chirag Shah <ch...@gmail.com>.
>Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?

If makeRequest is hitting a server under your control, you can use the
HTTP caching headers to dictate how long the response should be
cached. If you use this approach, make sure the refresh_interval
parameter is not set.

On Tue, Dec 22, 2009 at 3:57 AM, Bruce Godden
<br...@oerc.ox.ac.uk> wrote:
> Hi,
>
> I am working on a set of gadgets which use some shared data which is fetched using gadgets.io.makeRequest. I am using pubsub to pass messages between gadgets to tell them that they need to fetch new data. My problem is that Shindig is caching the data and so when it is refetched the old data is fetched again instead of the new data. I can work around this by avoiding caching (mostly) by setting the REFRESH_INTERVAL makeRequest parameter to a small number like 1 (or other more severe cache busting tricks) but I would actually like the data to be cached. Is there a technique that would allow me to force the Shindig cache to update when I know it is necessary?
>
> By the way, what is supposed to be the effect of setting REFRESH_INTERVAL to 0? My experience seems to show that it actually allows the data to be cached for a significant time rather than disallowing it completely. Is this expected?
>
> Bruce Godden
> Oxford e-Research Centre
>
>