gunnar: server/patches/horde HK-GW-framework_3.2_ALPHA-Share_caching.patch, NONE, 1.1 README_Share_caching.patch, NONE, 1.1

cvs at kolab.org cvs at kolab.org
Wed Oct 10 11:46:39 CEST 2007


Author: gunnar

Update of /kolabrepository/server/patches/horde
In directory doto:/tmp/cvs-serv22012/patches/horde

Added Files:
	HK-GW-framework_3.2_ALPHA-Share_caching.patch 
	README_Share_caching.patch 
Log Message:
The final Horde patch before the beta release. This intends to fix Horde Share caching for Kolab which is the second level of IMAP caching in Horde/Kolab.

--- NEW FILE: HK-GW-framework_3.2_ALPHA-Share_caching.patch ---
Fixes the share caching for the Share module.
* * *
Fixes the global share caching.

diff -r 3d04200d5eec framework/Kolab/Kolab/IMAP.php
--- a/framework/Kolab/Kolab/IMAP.php	Wed Oct 10 11:19:54 2007 +0200
+++ b/framework/Kolab/Kolab/IMAP.php	Wed Oct 10 11:20:13 2007 +0200
@@ -371,7 +371,18 @@ class Kolab_IMAP {
      */
     function listFolders()
     {
-        $folders = array();
+        require_once 'Horde/SessionObjects.php';
+
+        static $folders = array();
+
+        if (empty($folders)) {
+            $session = &Horde_SessionObjects::singleton();
+            $folders = &$session->query('horde_kolab_imaplist');
+        }
+
+        if (!empty($folders)) {
+            return $folders;
+        }
 
         // Connect to the IMAP server
         $imap = &Kolab_IMAP_Connection::singleton(Kolab::getServer('imap'),
@@ -417,6 +428,9 @@ class Kolab_IMAP {
 
             $folders[] = array($folder, $foldertype, $default);
         }
+
+        $session = &Horde_SessionObjects::singleton();
+        $session->overwrite('horde_kolab_imaplist', $folders, false);
 
         $imap->disconnect();
 
diff -r 3d04200d5eec framework/Share/Share/kolab.php
--- a/framework/Share/Share/kolab.php	Wed Oct 10 11:19:54 2007 +0200
+++ b/framework/Share/Share/kolab.php	Wed Oct 10 11:20:13 2007 +0200
@@ -66,6 +66,38 @@ class Horde_Share_kolab extends Horde_Sh
     }
 
     /**
+     * Initializes the object.
+     */
+    function __wakeup()
+    {
+        global $conf;
+
+        if (empty($conf['kolab']['enabled'])) {
+            Horde::fatal('You must enable the kolab settings to use the Kolab Share driver.', __FILE__, __LINE__);
+        }
+
+        foreach (array_keys($this->_cache) as $name) {
+            $this->_cache[$name]->setShareOb($this);
+            $this->_cache[$name]->storageObject->setStorage($this->_storage);
+        }
+
+        parent::__wakeup();
+    }
+
+    /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_sortList']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
      * Returns an array of all shares that $userid has access to.
      *
      * @param string  $userid       The userid of the user to check access for.
@@ -242,7 +274,14 @@ class Horde_Share_Storage_kolab {
     function Horde_Share_Storage_kolab($app)
     {
         $this->_app = $app;
-
+        return $this->__wakeup();
+    }
+
+    /**
+     * Initializes the object.
+     */
+    function __wakeup()
+    {
         // Connect to the IMAP server
         $this->_imap = &Kolab_IMAP_Connection::singleton(Kolab::getServer('imap'),
                                                          $GLOBALS['conf']['kolab']['imap']['port'],
@@ -254,6 +293,19 @@ class Horde_Share_Storage_kolab {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
+    }
+
+    /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_imap']);
+        $properties = array_keys($properties);
+        return $properties;
     }
 
     /**
@@ -363,10 +415,12 @@ class Horde_Share_Storage_kolab {
      * @param string $object  The share to fetch.
      * @param string $class   Subclass of Horde_Share_Object to use. Defaults
      *                        to ImapObject_Share.
+     * @param array  $perms   The permissions of the share if known
+     *
      * @return Horde_Share_Object_kolab  The share object or a PEAR error if
      *                                   the share was not found.
      */
-    function &getObject($object, $class = 'ImapObject_Share')
+    function &getObject($object, $class = 'ImapObject_Share', $perms = null)
     {
         if (empty($object)) {
             $error = PEAR::raiseError('No object requested.');
@@ -399,14 +453,17 @@ class Horde_Share_Storage_kolab {
             $object = $this->getDefaultShare();
         }
 
-        $share->setFolder($object);
-        $result = $share->accessible();
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("Share \"%s\" not accessible."), $object));
-        }
+        $share->setFolder($object, $perms);
+        /* FIXME: Is this call necessary at all? You should try to access a share that
+         *        cannot be accessed and see what happens.
+         *$result = $share->accessible();
+         *if (is_a($result, 'PEAR_Error')) {
+         *return $result;
+         *}
+         *if (!$result) {
+         *return PEAR::raiseError(sprintf(_("Share \"%s\" not accessible."), $object));
+         *}
+         */
         return $share;
     }
 
@@ -689,6 +746,19 @@ class Horde_Share_Object_kolab extends H
 class Horde_Share_Object_kolab extends Horde_Share_Object {
 
     /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_shareOb']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
      * Checks to see if a user has a given permission.
      *
      * @param string $userid       The userid of the user.
@@ -803,6 +873,19 @@ class ImapObject_Share {
     }
 
     /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_storage']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
      * Sets the storage driver for this storage object.
      *
      * @param Horde_Share_Storage_kolab $storage  A {@link Horde_Share_storage_kolab} instance.
@@ -810,6 +893,10 @@ class ImapObject_Share {
     function setStorage(&$storage)
     {
         $this->_storage = &$storage;
+        if (isset($this->_perm)) {
+            $imap = &$storage->getImap();
+            $this->_perm->setImap($imap);
+        }
     }
 
     /**
@@ -817,25 +904,29 @@ class ImapObject_Share {
      *
      * @param string  $folder  Name of the IMAP folder.
      * @param boolean $force   Enforce setting the folder.
-     */
-    function setFolder($folder, $force = false)
+     * @param array   $perms   The permissions of the folder if they are known
+     */
+    function setFolder($folder, $force = false, $perms = null)
     {
         if ($this->_folder == KOLAB_SHARE_INVALID || $force) {
             $this->_folder = $folder;
             if (isset($this->_perm)) {
                 $this->_perm->setFolder($folder);
             } else {
-                if ($this->exists()) {
-                    $perms = null;
-                } else {
-                    $perms = array('users' => array(Auth::getAuth() => PERMS_SHOW
-                                                                     | PERMS_READ
-                                                                     | PERMS_EDIT
-                                                                     | PERMS_DELETE));
+                if (empty($perms)) {
+                    if ($this->exists()) {
+                        // The permissions are unknown but the folder exists -> discover permissions
+                        $perms = null;
+                    } else {
+                        $perms = array('users' => array(Auth::getAuth() => PERMS_SHOW
+                                                                         | PERMS_READ
+                                                                         | PERMS_EDIT
+                                                                         | PERMS_DELETE));
+                    }
                 }
                 $perm = &new ImapFolder_Permission($folder,
                                                    $this->_storage->getImap(),
-                                                   $this, $perms);
+                                                   $this->getOwner(), $perms);
                 $this->setPermission($perm);
             }
         }
@@ -1265,11 +1356,11 @@ class ImapFolder_Permission extends Data
     var $data;
 
     /**
-     * The storage driver for this object.
-     *
-     * @var Horde_Share_Storage_kolab
-     */
-    var $_storage;
+     * Owner of the share.
+     *
+     * @var string
+     */
+    var $_owner;
 
     /**
      * The ImapFolder_Permission constructor.
@@ -1280,11 +1371,11 @@ class ImapFolder_Permission extends Data
      * @param Horde_Storage          $storage  A reference to the storage class
      * @param array                  $perms    A set of initial permissions.
      */
-    function ImapFolder_Permission($folder, &$imap, &$storage, $perms = null)
+    function ImapFolder_Permission($folder, &$imap, $owner, $perms = null)
     {
         $this->_folder = $folder;
         $this->_imap = &$imap;
-        $this->_storage = &$storage;
+        $this->_owner = $owner;
 
         // Load the permission from the folder now
         if (empty($perms)) {
@@ -1296,6 +1387,29 @@ class ImapFolder_Permission extends Data
         }
 
         $this->data = $perms;
+    }
+
+    /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_imap']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
+     * Sets the imap driver for this permission object.
+     *
+     * @param 
+     */
+    function setImap(&$imap)
+    {
+        $this->_imap = &$imap;
     }
 
     /**
@@ -1405,6 +1519,8 @@ class ImapFolder_Permission extends Data
      */
     function save()
     {
+        // FIXME: If somebody else accessed the folder before us, we will overwrite
+        //        the change here.
         $current = $this->getPerm();
 
         foreach ($this->data as $user => $user_perms) {
@@ -1482,7 +1598,7 @@ class ImapFolder_Permission extends Data
     function savePermission($user, $perms)
     {
         // Convert the horde permission style to IMAP permissions
-        $result = $user == $this->_storage->getOwner() ? 'a' : '';
+        $result = $user == $this->_owner ? 'a' : '';
         if ($perms & PERMS_SHOW) {
             $result .= 'l';
         }

--- NEW FILE: README_Share_caching.patch ---
DESCRIPTION:

This fixes the caching for the Kolab share driver and significantly
improves the Horde performance if you have many IMAP folders.

IMPACT:

Horde will be very slow if you have many IMAP folders.

REFERENCES:

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/horde/HORDE_3_2_ALPHA/summary

HISTORY

This is still rather fresh and might have side effects so this has not
yet been applied upstream even if it is Kolab specific.




More information about the commits mailing list