r45089 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45088‎ | r45089 | r45090 >
Date:13:32, 27 December 2008
Author:aaron
Status:resolved (Comments)
Tags:
Comment:
(bug 16774) Save CodeReview diffs to database instead of transitory cache
Modified paths:
  • /trunk/extensions/CodeReview/CodeRepository.php (modified) (history)
  • /trunk/extensions/CodeReview/archives/codereview-cr_diff.sql (added) (history)
  • /trunk/extensions/CodeReview/codereview.sql (modified) (history)

Diff [purge]

Index: trunk/extensions/CodeReview/codereview.sql
@@ -58,6 +58,11 @@
5959 -- * if the revision change only one file, the file path
6060 -- * else, common directory for all changes (e.g. trunk/phase3/includes/ )
6161 cr_path varchar(255) binary,
 62+
 63+ -- Text of the diff or ES url
 64+ cr_diff mediumblob NULL,
 65+ -- Text flags: gzip,utf-8,external
 66+ cr_flags tinyblob NOT NULL,
6267
6368 primary key (cr_repo_id, cr_id),
6469 key (cr_repo_id, cr_timestamp),
Index: trunk/extensions/CodeReview/archives/codereview-cr_diff.sql
@@ -0,0 +1,3 @@
 2+ALTER TABLE /*$wgDBprefix*/code_rev
 3+ ADD cr_diff mediumblob NULL,
 4+ ADD cr_flags tinyblob NOT NULL;
Property changes on: trunk/extensions/CodeReview/archives/codereview-cr_diff.sql
___________________________________________________________________
Name: svn:eol-style
15 + native
Index: trunk/extensions/CodeReview/CodeRepository.php
@@ -177,16 +177,19 @@
178178 * 'cached' to *only* fetch if cached
179179 */
180180 public function getDiff( $rev, $useCache = '' ) {
181 - global $wgMemc;
 181+ global $wgMemc, $wgDefaultExternalStore;
 182+ wfProfileIn( __METHOD__ );
182183
183184 $rev1 = $rev - 1;
184185 $rev2 = $rev;
185186
186187 $revision = $this->getRevision( $rev );
187188 if( $revision == null || !$revision->isDiffable() ) {
 189+ wfProfileOut( __METHOD__ );
188190 return false;
189191 }
190192
 193+ # Try memcached...
191194 $key = wfMemcKey( 'svn', md5( $this->mPath ), 'diff', $rev1, $rev2 );
192195 if( $useCache === 'skipcache' ) {
193196 $data = NULL;
@@ -194,12 +197,65 @@
195198 $data = $wgMemc->get( $key );
196199 }
197200
 201+ # Try the database...
 202+ if( !$data ) {
 203+ $dbr = wfGetDB( DB_SLAVE );
 204+ $row = $dbr->selectRow( 'code_rev',
 205+ array( 'cr_diff', 'cr_flags' ),
 206+ array( 'cr_repo_id' => $this->mId, 'cr_id' => $rev, 'cr_diff IS NOT NULL' ),
 207+ __METHOD__
 208+ );
 209+ if( $row ) {
 210+ $flags = explode( ',', $row->cr_flags );
 211+ $data = $row->cr_diff;
 212+ # Use external methods for external objects, text in table is URL-only then
 213+ if( in_array( 'external', $flags ) ) {
 214+ $url = $data;
 215+ @list(/* $proto */,$path) = explode('://',$url,2);
 216+ if( $path == "" ) {
 217+ $data = false; // something is wrong...
 218+ } else {
 219+ $data = ExternalStore::fetchFromURL($url);
 220+ }
 221+ }
 222+ // If the text was fetched without an error, convert it
 223+ if( $data !== false && in_array( 'gzip', $flags ) ) {
 224+ # Deal with optional compression of archived pages.
 225+ # This can be done periodically via maintenance/compressOld.php, and
 226+ # as pages are saved if $wgCompressRevisions is set.
 227+ $data = gzinflate( $data );
 228+ }
 229+ }
 230+ }
 231+
 232+ # Generate the diff as needed...
198233 if( !$data && $useCache !== 'cached' ) {
199234 $svn = SubversionAdaptor::newFromRepo( $this->mPath );
200235 $data = $svn->getDiff( '', $rev1, $rev2 );
 236+ // Store to cache
201237 $wgMemc->set( $key, $data, 3600*24*3 );
 238+ // Permanent DB storage
 239+ $flags = Revision::compressRevisionText( $data );
 240+ if( ($storage = $wgDefaultExternalStore) ) {
 241+ if( is_array($storage) ) {
 242+ # Distribute storage across multiple clusters
 243+ $store = $storage[mt_rand(0, count( $storage ) - 1)];
 244+ } else {
 245+ $store = $storage;
 246+ }
 247+ # Store and get the URL
 248+ $data = ExternalStore::insert( $store, $data );
 249+ if( $flags ) $flags .= ',';
 250+ $flags .= 'external';
 251+ }
 252+ $dbw = wfGetDB( DB_MASTER );
 253+ $dbw->update( 'code_rev',
 254+ array( 'cr_diff' => $data, 'cr_flags' => $flags ),
 255+ array( 'cr_repo_id' => $this->mId, 'cr_id' => $rev ),
 256+ __METHOD__
 257+ );
202258 }
203 -
 259+ wfProfileOut( __METHOD__ );
204260 return $data;
205261 }
206262

Follow-up revisions

RevisionCommit summaryAuthorDate
r45263Fix for r45089 -- return original diff data, not the compressed form, when do...brion23:13, 31 December 2008

Comments

#Comment by Brion VIBBER (talk | contribs)   19:04, 31 December 2008

Feels like it's duplicating too much of external store code, I'm a bit leery of it. Also not sure there's a clear way here to purge a bogus entry.

#Comment by Aaron Schulz (talk | contribs)   19:20, 31 December 2008

Maybe it could just not use ES afterall?

#Comment by Brion VIBBER (talk | contribs)   23:15, 31 December 2008

r45263 fixes display after the first fetch-and-store-to-DB when using ES or $wgCompressRevisions; Revision::compressRevisionText() replaces its parameter with the compressed form that would go into old_text etc, so we got gibberish shown on the first load.

Status & tagging log