r101479 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101478‎ | r101479 | r101480 >
Date:14:55, 1 November 2011
Author:catrope
Status:ok (Comments)
Tags:
Comment:
[RL2] Redesign memc key naming in CachedGadgetRepo, as promised in r101469. Introduce an abstract function CachedGadgetRepo::getCacheKey() that takes care of all cache key naming issues, and rethink the logic in ForeignDBGadgetRepo
Modified paths:
  • /branches/RL2/extensions/Gadgets/backend/CachedGadgetRepo.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/backend/ForeignDBGadgetRepo.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/backend/LocalGadgetRepo.php (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/backend/CachedGadgetRepo.php
@@ -1,5 +1,4 @@
22 <?php
3 -// TODO: Reconsider memc key naming
43 /**
54 * Abstract class that enhances GadgetRepo with caching. This is useful for
65 * repos that obtain gadget data from a database or a REST API. Currently, all
@@ -26,16 +25,6 @@
2726 */
2827 protected $idsLoaded = false;
2928
30 - /**
31 - * Memcached key of the gadget names list. Subclasses must set this in their constructor.
32 - * This could've been a static member if we had PHP 5.3's late static binding.
33 - *
34 - * Set to false if memcached is not available.
35 - *
36 - * TODO: make this an abstract getter, and redesign the whole memc key naming scheme
37 - */
38 - protected $namesKey;
39 -
4029 /*** Abstract methods ***/
4130
4231 /**
@@ -51,6 +40,14 @@
5241 */
5342 abstract protected function loadDataFor( $id );
5443
 44+ /**
 45+ * Get the memc key for caching the data for a given gadget, or for
 46+ * caching the gadget IDs list.
 47+ * @param $id string|null Gadget ID to get the memc key for, or null to get the memc key for the IDs list
 48+ * @return string Memc key including wiki prefix, i.e. the return value of wfMemcKey() or wfForeignMemcKey()
 49+ */
 50+ abstract protected function getCacheKey( $id );
 51+
5552 /*** Protected methods ***/
5653
5754 /**
@@ -79,14 +76,9 @@
8077 }
8178
8279 // Write to memc
83 - $key = $this->getMemcKey( 'gadgets', 'localrepodata', $id );
84 - if ( $key !== false ) {
85 - $wgMemc->set( $key, $toCache );
86 - }
 80+ $wgMemc->set( $this->getCacheKey( $id ), $toCache );
8781 // Clear the gadget names array in memc so it'll be regenerated later
88 - if ( $this->namesKey !== false ) {
89 - $wgMemc->delete( $this->namesKey );
90 - }
 82+ $wgMemc->delete( $this->getCacheKey( null ) );
9183 }
9284
9385 /*** Public methods inherited from GadgetRepo ***/
@@ -118,7 +110,8 @@
119111 }
120112
121113 // Try memc
122 - $cached = $this->namesKey !== false ? $wgMemc->get( $this->namesKey ) : false;
 114+ $key = $this->getCacheKey( null );
 115+ $cached = $wgMemc->get( $key );
123116 if ( is_array( $cached ) ) {
124117 // Yay, data is in cache
125118 // Add to $this->data , but let things already in $this->data take precedence
@@ -131,7 +124,7 @@
132125 // For memc, prepare an array with the IDs as keys but with each value set to null
133126 $toCache = array_combine( array_keys( $data ), array_fill( 0, count( $this->data ), null ) );
134127
135 - $wgMemc->set( $this->namesKey, $toCache );
 128+ $wgMemc->set( $key, $toCache );
136129 $this->idsLoaded = true;
137130 return array_keys( $this->data );
138131 }
@@ -160,9 +153,8 @@
161154 }
162155
163156 // Try cache
164 - // FIXME getMemcKey is defined in LocalGadgetRepo but not abstract. Cache key naming needs redesign
165 - $key = $this->getMemcKey( 'gadgets', 'localrepodata', $id );
166 - $cached = $key !== false ? $wgMemc->get( $key ) : false;
 157+ $key = $this->getCacheKey( $id );
 158+ $cached = $wgMemc->get( $key );
167159 if ( is_array( $cached ) ) {
168160 // Yay, data is in cache
169161 if ( count( $cached ) ) {
Index: branches/RL2/extensions/Gadgets/backend/LocalGadgetRepo.php
@@ -20,6 +20,14 @@
2121
2222 /*** Protected methods inherited from CachedGadgetRepo ***/
2323
 24+ protected function getCacheKey( $id ) {
 25+ if ( $id === null ) {
 26+ return wfMemcKey( 'gadgets', 'localrepoids' );
 27+ } else {
 28+ return wfMemcKey( 'gadgets', 'localrepodata', $id );
 29+ }
 30+ }
 31+
2432 protected function loadAllData() {
2533 $query = $this->getLoadAllDataQuery();
2634 $dbr = $this->getDB();
@@ -49,15 +57,6 @@
5058
5159 /*** Public methods inherited from GadgetRepo ***/
5260
53 - /**
54 - * Constructor.
55 - * @param info array of options. There are no applicable options for this class
56 - */
57 - public function __construct( array $options = array() ) {
58 - parent::__construct( $options );
59 - $this->namesKey = $this->getMemcKey( 'gadgets', 'localreponames' );
60 - }
61 -
6261 public function getSource() {
6362 return 'local';
6463 }
@@ -180,15 +179,6 @@
181180 }
182181
183182 /**
184 - * Get a memcached key. Subclasses can override this to use a foreign memc
185 - * @return string|bool Cache key, or false if this repo has no shared memc
186 - */
187 - protected function getMemcKey( /* ... */ ) {
188 - $args = func_get_args();
189 - return call_user_func_array( 'wfMemcKey', $args );
190 - }
191 -
192 - /**
193183 * Get the DB query to use in loadAllData(). Subclasses can override this to tweak the query.
194184 * @return Array
195185 */
Index: branches/RL2/extensions/Gadgets/backend/ForeignDBGadgetRepo.php
@@ -30,8 +30,6 @@
3131 foreach ( $optionKeys as $optionKey ) {
3232 $this->{$optionKey} = $options[$optionKey];
3333 }
34 -
35 - $this->namesKey = $this->getMemcKey( 'gadgets', 'foreigndbreponames' );
3634 }
3735
3836 public function isWriteable() {
@@ -67,13 +65,27 @@
6866 return $this->db;
6967 }
7068
71 - protected function getMemcKey( /* ... */ ) {
 69+ protected function getCacheKey( $id ) {
7270 if ( $this->hasSharedCache ) {
73 - $args = func_get_args();
74 - array_unshift( $args, $this->dbName, $this->tablePrefix );
75 - return call_user_func_array( 'wfForeignMemcKey', $args );
 71+ // Access the foreign wiki's memc
 72+ if ( $id === null ) {
 73+ // Use 'localrepoidsshared' instead of 'localrepoids', otherwise we
 74+ // will be accessing the same cache entry as the foreign wiki's LocalGadgetRepo
 75+ // We can't allow that to happen because the local repo's ID list includes
 76+ // shared gadgets but ours doesn't
 77+ return wfForeignMemcKey( $this->dbName, $this->tablePrefix, 'gadgets', 'localrepoidsshared' );
 78+ } else {
 79+ // We don't have to prevent collisions here because sharing gadget data
 80+ // caches between us and the foreign wiki's local repo is OK
 81+ return wfForeignMemcKey( $this->dbName, $this->tablePrefix, 'gadgets', 'localrepodata', $id );
 82+ }
7683 } else {
77 - return false;
 84+ // No access to the foreign wiki's memc, so cache locally
 85+ if ( $id === null ) {
 86+ return wfMemcKey( 'gadgets', 'foreignrepoids', $this->source );
 87+ } else {
 88+ return wfMemcKey( 'gadgets', 'foreignrepodata', $this->source, $id );
 89+ }
7890 }
7991 }
8092

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r101469[RL2] Factor the caching logic out of LocalGadgetRepo into CachedGadgetRepo, ...catrope13:13, 1 November 2011

Comments

#Comment by Nikerabbit (talk | contribs)   08:59, 16 December 2011

Why not let $id to default to null?

#Comment by Catrope (talk | contribs)   17:59, 16 December 2011

We could do that. I don't feel strongly about it either way.

Status & tagging log