8 Replies Latest reply on Jun 8, 2009 9:41 AM by gkiesel

    Caching of Ajax.js

    gkiesel

      Hello everybody!

      Using RichFaces (3.1.6) we recently had problems with a cached Ajax.js. For some (as yet unknown*) reason the content size for the script was (as shown in the http header) 0 bytes. As you can imagine this caused some undesirable behaviour in our application...
      The 0 bytes response seems to have been a one time occurence, but unfortunatly RichFaces adds "Cache-Control: max-age=86400" to the http-header when sending the script. So our webserver and proxies between webserver and client can (and do) cache the script up to a day. In effect the application is not usable for a whole day.

      What I wonder about is how RichFaces will deal with this problem when a change in Ajax.js (or another script returned in the same way) occures between versions. Will everybody have to stop their application for one day until the old script has vanished from caches before beeing able to deploy the new changed RichFaces version?

      I'd be happy to hear your thoughts on this.

      Regards,
      Gunnar

      ---
      * My guess is that an exception occured in ScriptRenderer.send() when calling jsmin.jsmin(). Any exception here would just be logged but not handled further. So in my opinion that could explain a response with a content size of 0 bytes and a http return code 200.

        • 1. Re: Caching of Ajax.js
          gkiesel

          Ok, I could just answer the version change question myself: the version no. is included in the returned uri so a new version would have a different one. Due to the new uri cached versions would become irrelevant.

          That leaves me wondering whether I'm correct about my assumption that an error occuring while reading/compressing the script stream could lead to a valid response without content, blocking the application from using ajax for atleast a day?
          Wouldn't it be better to also throw the exception as done when compression is turned of?

          • 2. Re: Caching of Ajax.js
            jbalunas

            Please use the RichFaces forum for user questions. This forum is specifically for design and development of the RichFaces project. I will move this post there.

            • 3. Re: Caching of Ajax.js
              gkiesel

              In my opinion discussing the way RichFaces handles internal errors is a development question. However I'm more interested in an answer then where the topic is located. ;o)

              • 4. Re: Caching of Ajax.js
                nbelaevski

                 

                "gkiesel" wrote:
                Ok, I could just answer the version change question myself: the version no. is included in the returned uri so a new version would have a different one. Due to the new uri cached versions would become irrelevant.

                Exactly.

                "gkiesel" wrote:
                That leaves me wondering whether I'm correct about my assumption that an error occuring while reading/compressing the script stream could lead to a valid response without content, blocking the application from using ajax for atleast a day?
                Wouldn't it be better to also throw the exception as done when compression is turned of?

                As far as I remember, this problem happened in one old version of Ajax4JSF - the first response came with '0' content-length, others were ok. That was not the issue in script minimization (scripts worked ok, furthermore you can turn the compression off), but coding error. Ctrl + F5 should solve the issue either as upgrade to a newer RF version (is it an option for you?).

                • 5. Re: Caching of Ajax.js

                  Hi,

                  we are facing a similar behavior and a update of the A4J-Libs would be a option for us. But can you tell me, what version causes that bug?

                  Thank you for your help anyway. :-)

                  Achim

                  • 6. Re: Caching of Ajax.js
                    gkiesel

                    Hello,

                    thank you for your answer.

                    Ctrl + F5 should solve the issue either as upgrade to a newer RF version (is it an option for you?).

                    Ctrl+F5 didn't help in our case. The proxy between client and app-server still returned the cached 0 byte script. Upgrading to a newer RF version is something we plan to do, but it requires a new app-server version and is thus no short term solution.

                    Let me show the piece of code that is the heart of the problem from my point of view from class ScriptRenderer (Revision: 1.1.2.1):
                    public int send(InternetResource base, ResourceContext context) throws IOException {
                     InputStream in = base.getResourceAsStream(context);
                     if (null == in) {
                     String message = Messages.getMessage(
                     Messages.NO_INPUT_STREAM_ERROR, base.getKey());
                     throw new IOException(message);
                     }
                     OutputStream out = context.getOutputStream();
                     // Compress JavaScript output by JSMin ( true by default )
                     if( ! "false".equalsIgnoreCase(context.getInitParameter(COMPRESS_SCRIPTS_PARAMETER))){
                     CountingOutputStream countingStream = new CountingOutputStream(out);
                     JSMin jsmin = new JSMin(in,countingStream);
                     try {
                     jsmin.jsmin();
                     } catch (Exception e) {
                     _log.error("Error send script to client for resource "+base.getKey(), e);
                     }
                     finally {
                     in.close();
                     countingStream.flush();
                     countingStream.close();
                     }
                     int written = countingStream.getWritten();
                     if(_log.isDebugEnabled()){
                     _log.debug("Send "+written+" bytes to client for JavaScript resource "+base.getKey());
                     }
                     return written;
                     } else {
                     return sendStream(in, out);
                     }
                     }
                    


                    I think the catch block when using the jsmin option should throw an exception and not just log it.

                    As Nick says turning compression of avoids the problem and that is what we did (however we ofcourse have to transfer some bytes more now).


                    • 7. Re: Caching of Ajax.js
                      nbelaevski

                       

                      I think the catch block when using the jsmin option should throw an exception and not just log it.

                      Browser doesn't show resources loading errors, so it's better to do explicit logging.

                      • 8. Re: Caching of Ajax.js
                        gkiesel

                         

                        Browser doesn't show resources loading errors, so it's better to do explicit logging.


                        Do log the error is definitely a good idea. But in this case an exception should be thrown as well.