Permalink
Browse files

Merge pull request #4 from brandonsavage/cache_changes

Changes to mediawiki-bugzilla from brandonsavage
  • Loading branch information...
2 parents 3a16e29 + 09b3ad8 commit 837eb807805b119e9f212768ad230bf290f55bb0 @LegNeato LegNeato committed Oct 24, 2011
Showing with 102 additions and 67 deletions.
  1. +8 −8 Bugzilla.php
  2. +4 −23 BugzillaJob.class.php
  3. +4 −34 BugzillaQuery.class.php
  4. +5 −1 cache.sql
  5. +12 −0 cache/BugzillaCacheI.class.php
  6. +68 −0 cache/BugzillaCacheMysql.class.php
  7. +1 −1 templates/bug/table.tpl
View
16 Bugzilla.php
@@ -18,14 +18,14 @@
// -----------------------------------------------------------------------------
// Register the classes to autoload
-$wgAutoloadClasses['Bugzilla'] = dirname(__FILE__) .
- '/Bugzilla.class.php';
-$wgAutoloadClasses['BugzillaQuery'] = dirname(__FILE__) .
- '/BugzillaQuery.class.php';
-$wgAutoloadClasses['BugzillaOutput'] = dirname(__FILE__) .
- '/BugzillaOutput.class.php';
-$wgAutoloadClasses['BugzillaJob'] = dirname(__FILE__) .
- '/BugzillaJob.class.php';
+$cwd = dirname(__FILE__); // We don't need to do this more than once!
+
+$wgAutoloadClasses['Bugzilla'] = $cwd . '/Bugzilla.class.php';
+$wgAutoloadClasses['BugzillaQuery'] = $cwd . '/BugzillaQuery.class.php';
+$wgAutoloadClasses['BugzillaOutput'] = $cwd . '/BugzillaOutput.class.php';
+$wgAutoloadClasses['BugzillaJob'] = $cwd . '/BugzillaJob.class.php';
+$wgAutoloadClasses['BugzillaCacheI'] = $cwd . '/cache/BugzillaCacheI.class.php';
+$wgAutoloadClasses['BugzillaCacheMysql'] = $cwd . '/cache/BugzillaCacheMysql.class.php';
// -----------------------------------------------------------------------------
// Register our background job
View
27 BugzillaJob.class.php
@@ -31,17 +31,8 @@ public function __construct( $title, $params ) {
public function _database_work() {
- // Get the master because we are writing
- $dbw = wfGetDB( DB_MASTER );
-
- // Add it to the cache
- $res = $dbw->insert(
- 'bugzilla_cache',
- array('id' => $this->query->id(),
- 'fetched_at' => wfTimestamp(TS_DB),
- 'data' => serialize($this->query->data)),
- __METHOD__
- );
+ $cache = new BugzillaCacheMysql();
+ $cache->set($this->query->id(), serialize($this->query->data));
}
@@ -55,18 +46,8 @@ public function __construct( $title, $params ) {
public function _database_work() {
- // Get the master because we are writing
- $dbw = wfGetDB( DB_MASTER );
-
- // Update cache entry
- $res = $dbw->update(
- 'bugzilla_cache',
- array('id' => $this->query->id(),
- 'fetched_at' => wfTimestamp(TS_DB),
- 'data' => serialize($this->query->data)),
- array('id' => $this->query->id()),
- __METHOD__
- );
+ $cache = new BugzillaCacheMysql();
+ $cache->set($this->query->id(), serialize($this->query->data));
}
}
View
38 BugzillaQuery.class.php
@@ -70,32 +70,13 @@ public function fetch() {
// Don't do anything if we already had an error
if( $this->error ) { return; }
-
- // Connect to the database. Because we are reading and we can deal with
- // a bit of stale data we can just look at the slave
- $dbr = wfGetDB( DB_SLAVE );
-
- // See if we have a cache entry
- // TODO: Make this configuratble between count(*) and what is here now
- $res = $dbr->select(
- 'bugzilla_cache',
- array('id', 'fetched_at','data'),
- 'id = "' . $this->id() . '"',
- __METHOD__,
- array( 'ORDER BY' => 'fetched_at DESC',
- 'LIMIT' => 1)
- );
+
+ $cache = new BugzillaCacheMysql();
+ $row = $cache->get($this->id());
// If the cache entry is older than this we need to invalidate it
$expiry = strtotime("-$wgBugzillaCacheMins minutes");
- // Check if there was an entry in the cache
- if( $res->numRows() ) {
- $row = $res->fetchRow();
- }else{
- $row = FALSE;
- }
-
if( !$row ) {
// No cache entry
@@ -105,20 +86,9 @@ public function fetch() {
// Does the Bugzilla query in the background and updates the cache
$job = new BugzillaInsertJob( $this->title, $params );
$job->insert();
-
- }elseif( $expiry > wfTimestamp(TS_UNIX, $row['fetched_at']) ) {
- // Cache entry is too old
-
- $this->cached = FALSE;
- $params = array( 'query_obj' => serialize($this) );
-
- // Does the Bugzilla query in the background and updates the cache
- $job = new BugzillaUpdateJob( $this->title, $params );
- $job->insert();
-
}else {
// Cache is good, use it
-
+
$this->id = $row['id'];
$this->fetched_at = wfTimestamp(TS_DB, $row['fetched_at']);
$this->data = unserialize($row['data']);
View
6 cache.sql
@@ -1,6 +1,10 @@
CREATE TABLE IF NOT EXISTS `bugzilla_cache` (
- `id` char(40) NOT NULL DEFAULT '',
+ `id` integer(40) NOT NULL AUTO_INCREMENT,
+ `key` varchar(255) NOT NULL DEFAULT '',
`fetched_at` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`data` longtext,
+ `expires` integer(11) NOT NULL DEFAULT 0
PRIMARY KEY (`id`)
) ENGINE=InnoDB, DEFAULT CHARSET=binary;
+
+CREATE UNIQUE INDEX `key_unique` ON `bugzilla_cache` (`key`);
View
12 cache/BugzillaCacheI.class.php
@@ -0,0 +1,12 @@
+<?php
+
+interface BugzillaCacheI
+{
+
+ public function set($key, $value, $ttl = 300);
+
+ public function get($key);
+
+ public function expire($key);
+
+}
View
68 cache/BugzillaCacheMysql.class.php
@@ -0,0 +1,68 @@
+<?php
+
+class BugzillaCacheMysql implements BugzillaCacheI
+{
+ protected $_slave;
+ protected $_master;
+
+ public function __construct()
+ {
+ // TO-DO: This methodology creates some difficulties to unit testing.
+ $this->_slave = wfGetDB( DB_SLAVE );
+ $this->_master = wfGetDB( DB_MASTER );
+ }
+
+ public function set($key, $value, $ttl = 300)
+ {
+ //TO-DO: It's probably a bad thing to write straight SQL against an
+ // abstraction layer. The abstraction layer doens't offer full
+ // functionality, though, and this reduces the number of queries
+ // for something as simple as caching. Also, the doQuery() method
+ // is marked "private" but that is commented out; that may change
+ // in a future release.
+ $key_c = $this->_master->strencode($key);
+ $value_c = $this->_master->strencode($value);
+ $date = wfTimestamp(TS_DB);
+ $now = time(); // Using time() because it's a PHP built-in.
+ $expires = $now+$ttl;
+
+ $sql = 'REPLACE INTO bugzilla_cache
+ (`key`, `fetched_at`, `data`, `expires`)
+ VALUES
+ ("%s", "%s", "%s", %d)';
+
+ $sql = sprintf($sql, $key_c, $date, $value_c, $expires);
+ $res = $this->_master->doQuery($sql);
+ return $res;
+ }
+
+ public function get($key)
+ {
+ $res = $this->_slave->select(
+ 'bugzilla_cache',
+ array('id', 'fetched_at', 'data', 'expires'),
+ '`key` = "' . $key . '"',
+ __METHOD__,
+ array( 'ORDER BY' => 'fetched_at DESC',
+ 'LIMIT' => 1)
+ );
+
+ $row = $res->fetchRow();
+
+ if(!$row || ($row['expires'] < time())) {
+ $this->expire($key); // This won't hurt us if the first condition is true.
+ return;
+ }
+
+ return $row;
+ }
+
+ public function expire($key)
+ {
+ return $this->_master->delete(
+ 'bugzilla_cache',
+ array('`key`="' . $key .'"')
+ );
+
+ }
+}
View
2 templates/bug/table.tpl
@@ -13,7 +13,7 @@
{foreach from=$bugs item=bug}
<tr>
<td>{$bug->id|escape}</td>
- <td><a href="{$bz_url}/showbug.cgi?id={$bug->id|escape:'url'}">{$bug->summary|escape}</a></td>
+ <td><a href="{$bz_url}/show_bug.cgi?id={$bug->id|escape:'url'}">{$bug->summary|escape}</a></td>
<td>{$bug->status|escape}</td>
<td>{$bug->priority|escape}</td>
</tr>

0 comments on commit 837eb80

Please sign in to comment.