Changeset 26411


Ignore:
Timestamp:
06/21/10 13:21:48 (7 years ago)
Author:
flack
Message:

re-implement NAP cache (still wip), refs #359

Location:
branches/developers/flack/acltuning/midcom.core/midcom
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/developers/flack/acltuning/midcom.core/midcom/config/midcom_config.php

    r26387 r26411  
    392392// Cache configuration
    393393$GLOBALS['midcom_config_default']['cache_base_directory'] = '/tmp/';
    394 $GLOBALS['midcom_config_default']['cache_autoload_queue'] = Array('content', /*'nap', */ 'phpscripts', 'memcache');
     394$GLOBALS['midcom_config_default']['cache_autoload_queue'] = Array('content', 'nap', 'phpscripts', 'memcache');
    395395
    396396// Content Cache
  • branches/developers/flack/acltuning/midcom.core/midcom/helper/_basicnav.php

    r26407 r26411  
    202202        $this->_root = $tmp->id;
    203203
    204         // $this->_nap_cache = $_MIDCOM->cache->nap->get_nap_cache($GLOBALS['midcom_config']['midcom_root_topic_guid']);
     204        $this->_nap_cache = $_MIDCOM->cache->nap;
    205205
    206206        $this->_leaves = array();
     
    227227
    228228        $root_set = false;
     229
    229230        foreach ($node_path_candidates as $node_id)
    230231        {
     
    234235                    if (!$root_set)
    235236                    {
     237                        //var_dump(self::$_nodes);
     238
    236239                        // Reset the Root node's URL Parameter to an empty string.
    237240                        self::$_nodes[$this->_root][MIDCOM_NAV_URL] = '';
     
    287290
    288291        $topic = midcom_db_topic::get_cached($topic_id);
     292
    289293        if (   !$topic
    290294            || !$topic->guid)
     
    394398            return MIDCOM_ERRFORBIDDEN;
    395399        }
     400
    396401        // The node is visible, add it to the list.
    397402        self::$_nodes[$nodedata[MIDCOM_NAV_ID]] = $nodedata;
     403
    398404        $this->_guid_map[$nodedata[MIDCOM_NAV_GUID]] =& self::$_nodes[$nodedata[MIDCOM_NAV_ID]];
    399405
     
    429435     * cache, it is retrieved from there. (NOTE: Cache has been disabled. See #252 at Tigris.org.)
    430436     *
    431      * @param mixed $id The ID of the node for which the NAP information is requested.
     437     * @param mixed $topic The node for which the NAP information is requested.
    432438     * @param mixed $up    The node ID of the parent node.    Optional and not normally needed.
    433439     * @return Array NAP node data structure or NULL in case no NAP information is available for this topic.
    434440     * @access private
    435441     */
    436     private function _get_node($id, $up = null)
    437     {
    438         /*
     442    private function _get_node($topic, $up = null)
     443    {
     444        $nodedata = false;
     445       
    439446        if (!$up)
    440447        {
    441             $this->_nap_cache->open();
    442             if ($this->_nap_cache->exists($id))
    443             {
    444                 debug_add("Cache hit for the guid {$id}.");
    445                 $nodedata = $this->_nap_cache->get($id);
    446                 $this->_nap_cache->close();
    447             }
    448             else
    449             {
    450                 debug_add("No cache hit for the guid {$id}.");
    451                 $this->_nap_cache->close();
    452 
    453                 $nodedata = $this->_get_node_from_database($id, $up);
    454                 $this->_nap_cache->put($id, $nodedata);
    455                 debug_add("Added the guid {$id} to the cache.");
    456             }
    457         }
    458         */
    459         // Cache disabled, see http://midcom.tigris.org/issues/show_bug.cgi?id=252
    460         $nodedata = $this->_get_node_from_database($id, $up);
    461 
    462         if (is_null($nodedata))
    463         {
    464             debug_push_class(__CLASS__, __FUNCTION__);
    465             debug_add('We got NULL for this node, so we do not have any NAP information, returning null directly.');
    466             debug_pop();
    467             return null;
     448            $nodedata = $this->_nap_cache->get_node($topic->id);
     449        }
     450
     451        if (!$nodedata)
     452        {
     453            $nodedata = $this->_get_node_from_database($topic, $up);
     454            if (is_null($nodedata))
     455            {
     456                debug_push_class(__CLASS__, __FUNCTION__);
     457                debug_add('We got NULL for this node, so we do not have any NAP information, returning null directly.');
     458                debug_pop();
     459                return null;
     460            }
     461
     462            $this->_nap_cache->put($topic->id, $nodedata);
     463            debug_add("Added the guid {$topic->id} to the cache.");
    468464        }
    469465
     
    666662        $entry_name = "{$node[MIDCOM_NAV_ID]}-leaves";
    667663
    668         /*
    669         $this->_nap_cache->open();
    670         if ($this->_nap_cache->exists($entry_name))
    671         {
    672             $leaves = $this->_nap_cache->get($entry_name);
    673         }
    674         else
    675         {
    676             $leaves = null;
    677         }
    678         $this->_nap_cache->close();
    679         */
    680         // Cache disabled, see http://midcom.tigris.org/issues/show_bug.cgi?id=252
    681         $leaves = null;
    682 
    683         if (is_null($leaves))
    684         {
    685             // Apparently, the leaves have not yet been loaded for this topic, so we have to do this now.
    686             // Afterwards we update the cache.
     664        $leaves = $this->_nap_cache->get_leaves($entry_name);
     665
     666        if (!$leaves)
     667        {
    687668            debug_push_class(__CLASS__, __FUNCTION__);
    688669            debug_add('The leaves have not yet been loaded from the database, we do this now.');
    689670            debug_pop();
     671
     672            //we always write all the leaves to cache and filter for ACLs after the fact
     673            $_MIDCOM->auth->request_sudo('midcom.helper.nav');
    690674            $leaves = $this->_get_leaves_from_database($node);
    691 
    692             // Cache disabled, see http://midcom.tigris.org/issues/show_bug.cgi?id=252
    693             // $this->_write_leaves_to_cache($node, $leaves);
    694         }
     675            $_MIDCOM->auth->drop_sudo();
     676
     677            $this->_write_leaves_to_cache($node, $leaves);
     678        }
     679
     680        $user_id = $_MIDCOM->auth->acl->get_user_id();
     681
     682        $result = array();
     683        foreach ($leaves as $id => $data)
     684        {
     685            if (   isset($data[MIDCOM_NAV_OBJECT])
     686                && is_object($data[MIDCOM_NAV_OBJECT])
     687                && $data[MIDCOM_NAV_OBJECT]->guid)
     688            {
     689                if (    $user_id
     690                    && !$_MIDCOM->auth->acl->can_do_byguid('midgard:read', $data[MIDCOM_NAV_OBJECT]->guid, get_class($data[MIDCOM_NAV_OBJECT]), $user_id))
     691                {
     692                    continue;
     693                }
     694
     695                //workaround for a strange bug where all ids in Memcache are 0
     696                if ($data[MIDCOM_NAV_OBJECT]->id == 0)
     697                {
     698                    $mc = new midgard_collector($data[MIDCOM_NAV_OBJECT]->__mgdschema_class_name__, 'guid', $data[MIDCOM_NAV_OBJECT]->guid);
     699                    $mc->set_key_property('id');
     700                    $mc->execute();
     701                    $ids = $mc->list_keys();
     702                       
     703                    if (empty($ids))
     704                    {
     705                        continue;
     706                    }
     707
     708                    $data[MIDCOM_NAV_OBJECT]->id = key($ids);
     709                }
     710
     711                $result[$id] = $data;
     712            }
     713        }
     714
    695715
    696716        // Post process the leaves for URLs and the like.
    697717        // Rewrite all host dependant URLs based on the relative URL within our topic tree.
    698         $this->_update_leaflist_urls($leaves);
     718        $this->_update_leaflist_urls($result);
    699719
    700720        // Don't log, this can get really big.
    701         // debug_print_r("We will return these leaves:", $leaves);
    702 
    703         return $leaves;
     721        // debug_print_r("We will return these leaves:", $result);
     722
     723        return $result;
    704724    }
    705725
     
    915935
    916936        // We need to update the node too, as it contains the leaf list for rapid access.
    917         $node_leaflist = array_keys($leaves);
    918 
    919         $this->_nap_cache->open(true);
    920 
    921         if (! $this->_nap_cache->exists($node[MIDCOM_NAV_ID]))
    922         {
    923             $this->_nap_cache->close();
     937        //$node_leaflist = array_keys($leaves);
     938
     939        $cached_node = $this->_nap_cache->get_node($node[MIDCOM_NAV_ID]);
     940
     941        if (!$cached_node)
     942        {
    924943            debug_add("NAP Caching Engine: Tried to update the topic {$node[MIDCOM_NAV_NAME]} (#{$node[MIDCOM_NAV_OBJECT]->id}) "
    925944                . 'which was supposed to be in the cache already, but failed to load the object from the database. '
     
    931950        // We load it again to get the cached structure, not the completed one from the
    932951        // in-memory cache.
    933         $cached_node = $this->_nap_cache->get($node[MIDCOM_NAV_ID]);
    934         $cached_node[MIDCOM_NAV_LEAVES] = $node_leaflist;
    935 
    936         debug_print_r('Updating the Node structure in the cache to this:', $cached_node);
    937         $this->_nap_cache->put($node[MIDCOM_NAV_ID], $cached_node);
     952
     953        //$cached_node[MIDCOM_NAV_LEAVES] = $node_leaflist;
     954
     955        //debug_print_r('Updating the Node structure in the cache to this:', $cached_node);
     956        //$this->_nap_cache->put($node[MIDCOM_NAV_ID], $cached_node);
    938957
    939958        $this->_nap_cache->put("{$node[MIDCOM_NAV_ID]}-leaves", $leaves);
    940959
    941         $this->_nap_cache->close();
    942960        debug_pop();
    943961    }
     
    10111029            $subnode = midcom_db_topic::get_cached($guid);
    10121030            $subnode_id = $this->_nodeid($subnode->id, $up);
     1031
    10131032            if ($this->_loadNode($subnode_id, $up) !== MIDCOM_ERROK)
    10141033            {
     
    11631182            $node_id = $node->id;
    11641183        }
    1165 
    11661184        if ($this->_loadNode($node_id) != MIDCOM_ERROK)
    11671185        {
  • branches/developers/flack/acltuning/midcom.core/midcom/services/cache/module/nap.php

    r25326 r26411  
    4848     */
    4949
     50   
    5051    /**
    5152     * The configuration to use to start up the backend drivers. Initialized during
    5253     * startup from the MidCOM configuration key cache_module_nap_backend.
    53      *
     54     * 
    5455     * @var Array
    5556     */
    56     var $_backend_config = null;
    57 
    58     /**
    59      * This array maps GUIDs to backend instances. See _check_for_topic() for details.
    60      *
    61      * @var Array
    62      */
    63     var $_guid_backend_map = Array();
     57    var $_backend = null;
     58   
     59    /**
     60     * The cache backend instance to use.
     61     * 
     62     * @var midcom_services_cache_backend
     63     */
     64    var $_cache = null;
    6465
    6566    /**#@-*/
     
    8283    function _on_initialize()
    8384    {
    84         $this->_backend_config = $GLOBALS['midcom_config']['cache_module_nap_backend'];
    85         if (! array_key_exists('directory', $this->_backend_config))
    86         {
    87             $this->_backend_config['directory'] = 'nap/';
    88         }
    89         if (! array_key_exists('driver', $this->_backend_config))
    90         {
    91             $this->_backend_config['driver'] = 'dba';
    92         }
    93         $this->_backend_config['auto_serialize'] = true;
    94 
    95         $this->_check_for_topic($GLOBALS['midcom_config']['midcom_root_topic_guid']);
    96     }
    97 
    98     /**
    99      * Returns the NAP cache associated with the topic tree identified by the
    100      * parameter $root_topic_guid. The constructed cache database name will be
    101      * "NAP_{$root_topic_guid}".
    102      *
    103      * It verifies, that the cache databases related to the root topic
    104      *
    105      * @param GUID $root_topic_guid The GUID of the root topic which is looked for.
    106      */
    107     function & get_nap_cache ($root_topic_guid)
    108     {
    109         $this->_check_for_topic($root_topic_guid);
    110         return $this->_guid_backend_map[$root_topic_guid];
    111     }
    112 
    113     /**
    114      * Internal helper, which ensures that the cache databases for root topic guid
    115      * passed to the function are loaded.
    116      *
    117      * @param GUID $root_topic_guid The GUID of the root topic which is looked for.
    118      * @access private
    119      */
    120     function _check_for_topic ($guid)
    121     {
    122         if (! array_key_exists($guid, $this->_guid_backend_map))
    123         {
    124             $topic = new midcom_db_article($guid);
    125             // Don't use generate_error, as there is no MidCOM instance there yet.
    126             if (! $topic)
    127             {
    128                 debug_print_r("Retrieved topic was: ", $topic);
    129                 die("Tried to load the topic {$guid} for NAP cache backend creation, which failed: " . midcom_application::get_error_string());
    130             }
    131 
    132             $this->_guid_backend_map[$guid] = $this->_create_backend("NAP_{$guid}", $this->_backend_config);
     85        $this->_backend = $GLOBALS['midcom_config']['cache_module_memcache_backend'];
     86       
     87        if ($this->_backend)
     88        {
     89            $config = $GLOBALS['midcom_config']['cache_module_memcache_backend_config'];
     90            $config['driver'] = $this->_backend;
     91            $this->_cache = $this->_create_backend('module_nap', $config);
    13392        }
    13493    }
     
    164123    function invalidate($guid)
    165124    {
    166         debug_push_class(__CLASS__, __FUNCTION__);
    167 
    168125        $nav = new midcom_helper_nav();
    169126        $napobject = $nav->resolve_guid($guid);
     
    172129        {
    173130            // Ignoring this should be safe, see the method documentation for details.
    174 
     131            debug_push_class(__CLASS__, __FUNCTION__);
    175132            debug_add("We failed to resolve the GUID {$guid} with NAP, apparently it is not cached or no valid NAP node, skipping it therefore.",
    176133                MIDCOM_LOG_INFO);
     
    179136        }
    180137
    181         $rootnode = $nav->get_node($nav->get_root_node());
    182         $nap_cache = $this->get_nap_cache($rootnode[MIDCOM_NAV_GUID]);
    183 
    184138        if ($napobject[MIDCOM_NAV_TYPE] == 'leaf')
    185139        {
     
    190144            $node_id = $napobject[MIDCOM_NAV_ID];
    191145        }
    192 
    193         $nap_cache->open(true);
    194         if ($nap_cache->exists($node_id))
    195         {
    196             $nap_cache->remove($node_id);
    197         }
    198         else
    199         {
    200             debug_add("The node was not found in the cache, ignoring it though, as there is obviosuly nothing to invalidate then.",
    201                 MIDCOM_LOG_WARN);
    202         }
    203 
    204146        $leaves_key = "{$node_id}-leaves";
    205         if ($nap_cache->exists($leaves_key))
    206         {
    207             $nap_cache->remove($leaves_key);
    208         }
    209         else
    210         {
    211             debug_add("The node was not found in the cache, ignoring it though, as there is obviosuly nothing to invalidate then.",
    212                 MIDCOM_LOG_WARN);
    213         }
    214 
    215         debug_pop();
    216     }
    217 
    218 
    219 
     147
     148        $this->_cache->remove("NAP-{$node_id}");
     149        $this->_cache->remove("NAP-{$leaves_key}");
     150    }
     151
     152    /**
     153     * Looks up a node in the cache and returns it. Not existent
     154     * keys are caught in this call as well, so you do not need
     155     * to call exists first.
     156     *
     157     * @param string $key The key to look up.
     158     * @return mixed The cached value on success, false on failure.
     159     */
     160    function get_node($key)
     161    {
     162        if ($this->_cache === null)
     163        {
     164            return false;
     165        }
     166
     167        // Objects seem to lose their IDs sometimes when restoring form cache, so make sure they are set correctly
     168        $data = $this->_cache->get("NAP-{$key}");
     169
     170        if (   $data
     171            && isset($data[MIDCOM_NAV_OBJECT])
     172            && is_object($data[MIDCOM_NAV_OBJECT])
     173            && $data[MIDCOM_NAV_OBJECT]->id == 0)
     174        {
     175            $data[MIDCOM_NAV_OBJECT]->id = (int) $data[MIDCOM_NAV_ID];
     176        }
     177
     178        return $data;
     179    }
     180
     181    /**
     182     * Looks up a node in the cache and returns it. Not existent
     183     * keys are caught in this call as well, so you do not need
     184     * to call exists first.
     185     *
     186     * @param string $key The key to look up.
     187     * @return mixed The cached value on success, false on failure.
     188     */
     189    function get_leaves($key)
     190    {
     191        if ($this->_cache === null)
     192        {
     193            return false;
     194        }
     195
     196        return $this->_cache->get("NAP-{$key}");
     197    }
     198
     199
     200    /**
     201     * Checks for the existence of a key in the cache.
     202     *
     203     * @param string $key The key to look up.
     204     * @return boolean Indicating existence
     205     */
     206    function exists($key)
     207    {
     208        if ($this->_cache === null)
     209        {
     210            return false;
     211        }
     212       
     213        return $this->_cache->exists("NAP-{$key}");
     214    }
     215   
     216    /**
     217     * Sets a given key in the cache. If the data group is unknown, a Warning-Level error
     218     * is logged and putting is denied.
     219     *
     220     * @param string $key The key to look up.
     221     * @param mixed $data The data to store.
     222     * @param int $timeout how long the data should live in the cache.
     223     */
     224    function put($key, $data, $timeout = FALSE)
     225    {
     226        if ($this->_cache === null)
     227        {
     228            return;
     229        }
     230
     231        $this->_cache->put("NAP-{$key}", $data, $timeout);
     232    }
    220233
    221234}
Note: See TracChangeset for help on using the changeset viewer.