[icinga-checkins] icinga.org: icinga-web/r1.8: Improved squishloader performance, especially when returning 304 NOT MODIFIED

git at icinga.org git at icinga.org
Mon Jan 14 13:41:51 CET 2013


Module: icinga-web
Branch: r1.8
Commit: b7f1bdb87cf8cbc39d7dbb2ae0b2460a88d13d28
URL:    https://git.icinga.org/?p=icinga-web.git;a=commit;h=b7f1bdb87cf8cbc39d7dbb2ae0b2460a88d13d28

Author: Jannis Mosshammer <jannis.mosshammer at netways.de>
Date:   Mon Dec 17 11:55:19 2012 +0100

Improved squishloader performance, especially when returning 304 NOT MODIFIED

---

 .../actions/Widgets/SquishLoaderAction.class.php   |   44 +++++++-------
 .../models/SquishFileContainerModel.class.php      |   30 ++++++----
 .../Widgets/SquishLoaderSuccessView.class.php      |   63 +++++--------------
 3 files changed, 57 insertions(+), 80 deletions(-)

diff --git a/app/modules/AppKit/actions/Widgets/SquishLoaderAction.class.php b/app/modules/AppKit/actions/Widgets/SquishLoaderAction.class.php
index b77b165..59c52ce 100644
--- a/app/modules/AppKit/actions/Widgets/SquishLoaderAction.class.php
+++ b/app/modules/AppKit/actions/Widgets/SquishLoaderAction.class.php
@@ -29,20 +29,30 @@ class AppKit_Widgets_SquishLoaderAction extends AppKitBaseAction {
     }
 
     public function executeRead(AgaviRequestDataHolder $rd) {
-        $ra = explode('.', array_pop(
-                          $this->getContext()->getRequest()->getAttribute(
-                              'matched_routes', 'org.agavi.routing'
-                          )
-                      ));
-
-        $type = array_pop($ra);
+        $headers = $rd->getHeaders();
+        $route =  $this->getContext()->getRequest()->getAttribute(
+            'matched_routes', 'org.agavi.routing'
+        );
 
+        $route = $route[count($route)-1];
+        $type = explode(".",$route);
+        $type = $type[count($type)-1];
         $loader = $this->getContext()->getModel(
                       'SquishFileContainer',
                       'AppKit',
-                      array('type' => $type)
+                      array(
+                          'type' => $type,
+                          'route' => $route
+                      )
                   );
+        if (isset($headers['IF_NONE_MATCH'])) {
+            $etag = str_replace('"',"",$headers['IF_NONE_MATCH']);
+            if($loader->hasEtagInCache($etag)) {
+                header("HTTP/1.1 304 NOT MODIFIED");
+                die();
+            }
 
+        }
         $resources = $this->getContext()->getModel('Resources', 'AppKit');
 
         switch ($type) {
@@ -72,21 +82,11 @@ class AppKit_Widgets_SquishLoaderAction extends AppKitBaseAction {
                 break;
         }
 
-        $headers = $rd->getHeaders();
-        $etag = rand();
-
-        if (isset($headers['IF_NONE_MATCH'])) {
-            $etag = str_replace('"',"",$headers['IF_NONE_MATCH']);
-        }
-
-        if (!$loader->squishContents($etag)) {
-            $content = $loader->getContent();
-            $this->setAttribute('content', $content. chr(10));
-        } else {
-            $this->setAttribute('existsOnClient',true);
-        }
 
-        $this->setAttribute('etag',$loader->getChecksum());
+        $loader->squishContents();
+        $content = $loader->getContent();
+        $this->setAttribute('content', $content. chr(10));
+        $this->setAttribute("etag",$loader->getCachedChecksum());
 
         return $this->getDefaultViewName();
     }
diff --git a/app/modules/AppKit/models/SquishFileContainerModel.class.php b/app/modules/AppKit/models/SquishFileContainerModel.class.php
index d4f215e..613704d 100644
--- a/app/modules/AppKit/models/SquishFileContainerModel.class.php
+++ b/app/modules/AppKit/models/SquishFileContainerModel.class.php
@@ -29,6 +29,7 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
     private $files          = array();
     private $actions        = array();
     private $type           = null;
+    private $route          = "";
     private $content        = null;
     private $checksum       = null;
     private $maxCacheTime   = 14400;
@@ -43,7 +44,9 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
         if (array_key_exists('type', $parameters)) {
             $this->setType($parameters['type']);
         }
-
+        if (array_key_exists('route', $parameters)) {
+            $this->route = $parameters['route'];
+        }
         parent::initialize($context, $parameters);
         $cfg = AgaviConfig::get('modules.appkit.squishloader');
 
@@ -105,15 +108,15 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
         return $this->type;
     }
 
-    public function squishContents($lastSquish = null) {
-        if ($lastSquish) {
-            $this->getCachedChecksum();
+    public function hasEtagInCache($squishEtag) {
+        $sum = $this->getCachedChecksum();
+
+        return $sum && ($sum == $squishEtag);
+
+    }
+
+    public function squishContents() {
 
-            if ($lastSquish == $this->checksum) {
-                return true;
-            }
-        }
-        
         if ($this->useCaching) {
             $this->readCached();
         }
@@ -166,11 +169,11 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
             }
         }
 
-        return $lastSquish && $lastSquish == $this->checksum;
+        return true;
     }
 
     private function getCacheFilename() {
-        $file = "squish_".md5(implode(";",$this->files));
+        $file = "squish_".md5($this->route);
 
         $cached = $this->cache_dir.'/'.$file;
 
@@ -205,7 +208,9 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
         return null;
     }
 
-    private function getCachedChecksum() {
+    public function getCachedChecksum() {
+        if($this->checksum)
+            return $this->checksum;
         $cached = $this->getCacheFilename().".sum";
 
         if (is_readable($cached) && file_exists($cached)) {
@@ -214,6 +219,7 @@ class AppKit_SquishFileContainerModel extends AppKitBaseModel {
             }
 
             $this->checksum = file_get_contents($cached);
+            return $this->checksum;
         }
 
         return null;
diff --git a/app/modules/AppKit/views/Widgets/SquishLoaderSuccessView.class.php b/app/modules/AppKit/views/Widgets/SquishLoaderSuccessView.class.php
index b11f8a1..3157a30 100644
--- a/app/modules/AppKit/views/Widgets/SquishLoaderSuccessView.class.php
+++ b/app/modules/AppKit/views/Widgets/SquishLoaderSuccessView.class.php
@@ -28,49 +28,20 @@ class AppKit_Widgets_SquishLoaderSuccessView extends AppKitBaseView {
         if ($this->getAttribute('errors', false)) {
             return "throw '". join(", ", $this->getAttribute('errors')). "';";
         } else {
-    
-            $content = '';    
-            $this->copyConfigToJavascript($content);
-            $content .= $this->getAttribute('content');
-            
-            $etag = $this->getAttribute("etag",rand());
-            
-            $this->getResponse()->setHttpHeader('Cache-Control', 'private', true);
-            $this->getResponse()->setHttpHeader('Pragma', null, true);
-            $this->getResponse()->setHttpHeader('Expires', null, true);
-            $this->getResponse()->setHttpHeader('ETag', '"'. $etag. '"', true);
+            // Only cache in browser, not in proxys
+            header('Cache-Control: private', true);
+            header('Pragma: no-cache', true);
 
-            if ($this->getAttribute('existsOnClient',false)) {
-                $this->getResponse()->setHttpStatusCode("304");
-                return "";
-            }
-            
-            $options = AgaviConfig::get('modules.appkit.squishloader', array());
-            $gz_level = isset($options['gzcompress_level']) ? 
-                (integer)$options['gzcompress_level'] : 3;
-            $gz_use = isset($options['use_gzcompress']) ?
-                (boolean)$options['use_gzcompress'] : false;  
-            
-            if ($gz_use === true) {
-                
-                $encoding = $rd->getHeader('ACCEPT_ENCODING', false);
-                
-                if (strpos($encoding, 'gzip') !== false) {
-                    $encoding = 'gzip';
-                } elseif(strpos($encoding, 'x-gzip') !== false) {
-                    $encoding = 'x-gzip';
-                }
-                
-                if ($encoding !== false) {
-                    header('Content-Encoding: '. $encoding);
-                    $l = strlen($content);

-                    $content = gzcompress($content, 4);

-                    $content = substr($content, 0, $l);
-                    return "\x1f\x8b\x08\x00\x00\x00\x00\x00". $content;
-                }
-            }
-            
-            return $content;
+            header('Expires: '.date("r",time()+60*60*24));
+            header('ETag: "'. $this->getAttribute("etag",rand()). '"', true);
+            header('Content-Type: text/javascript',true);
+
+
+            $this->printJSConfig();
+            echo $this->getAttribute('content');
+
+
+            return "";
         }
     }
 
@@ -88,15 +59,15 @@ class AppKit_Widgets_SquishLoaderSuccessView extends AppKitBaseView {
      * Mapping configuration items from AgaviConfig to JS AppKit.util.Config
      * @param string $content 
      */
-    private function copyConfigToJavascript(&$content) {
+    private function printJSConfig() {
         $map = AgaviConfig::get('modules.appkit.js_config_mapping', array ());
         if (count($map)) {
-            $out = 'var Icinga = { AppKit: { configMap: {} }};'. chr(10);
+            echo 'var Icinga = { AppKit: { configMap: {} }};'. chr(10);
             foreach ($map as $target=>$source) {
                 $val = AgaviConfig::get($source ? $source : $target, null);
-                $out .= 'Icinga.AppKit.configMap['. json_encode($target). '] = '. json_encode($val). ';'. chr(10);
+                echo 'Icinga.AppKit.configMap['. json_encode($target). '] = '. json_encode($val). ';'. chr(10);
             }
-            $content .= $out;
+
         }
     }
 





More information about the icinga-checkins mailing list