Skip to content

Commit

Permalink
Add some logging to the caching.
Browse files Browse the repository at this point in the history
In the process, streamline some of the caching-related code.
  • Loading branch information
conormcd committed Nov 20, 2014
1 parent b6cd44a commit 832245a
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 191 deletions.
14 changes: 8 additions & 6 deletions controller/Controller.php
Expand Up @@ -83,12 +83,14 @@ protected function content() {
if ($model) {
$key .= $model->eTag();
}
$content = Cache::get($key);
if (!$content) {
$content = Mustache::render($view, $model);
Cache::set($key, $content, 86400 + rand(0, 3600));
}
return $content;

return Cache::run(
$key,
86400 + rand(0, 3600),
function () use ($view, $model) {
return Mustache::render($view, $model);
}
);
}

/**
Expand Down
26 changes: 26 additions & 0 deletions lib/Cache.php
Expand Up @@ -52,6 +52,32 @@ public static function clear() {
apc_clear_cache('user');
}
}

/**
* Run some code and cache the result.
*
* @param string $key The key for the cache entry.
* @param int $ttl The life time for the cache entry.
* @param callable $callable The code to run and cache.
* @param array $args Arguments to pass to the cached function.
*
* @return mixed The result of the wrapped, possibly from the
* cache.
*/
public static function run($key, $ttl, $callable, $args = array()) {
$result = self::get($key);
if ($result === null) {
$start = microtime(true);
$result = call_user_func_array($callable, $args);
Logger::debug(
"Value recomputed for $key in " .
(microtime(true) - $start) .
" seconds."
);
self::set($key, $result, $ttl);
}
return $result;
}
}

?>
151 changes: 79 additions & 72 deletions lib/Flickr.php
Expand Up @@ -50,25 +50,27 @@ public function __construct($key, $secret, $user) {
* @return array See {@link PhotoProvider#getAlbum()}
*/
public function getAlbums() {
$key = 'FLICKR_ALBUMS';
$albums = Cache::get($key);
if (!$albums) {
$albums = array();
$response = $this->photosets->getList(
array('user_id' => $this->getCurrentUserNSID())
);
foreach ($response['photosets']['photoset'] as $set) {
$albums[] = new PhotoAlbumModel(
$this,
$set['id'],
$set['title']['_content'],
$set['date_create'],
$set['primary']
$flickr = $this;
return Cache::run(
'FLICKR_ALBUMS',
3600 + rand(0, 300),
function () use ($flickr) {
$albums = array();
$response = $flickr->photosets->getList(
array('user_id' => $flickr->getCurrentUserNSID())
);
foreach ($response['photosets']['photoset'] as $set) {
$albums[] = new PhotoAlbumModel(
$flickr,
$set['id'],
$set['title']['_content'],
$set['date_create'],
$set['primary']
);
}
return $albums;
}
Cache::set($key, $albums, 3600 + rand(0, 300));
}
return $albums;
);
}

/**
Expand Down Expand Up @@ -99,40 +101,42 @@ public function getAlbum($album_short_name) {
* @return array See {@link PhotoProvider#getAlbum()}
*/
public function getPhotos($album) {
$key = 'FLICKR_PHOTOS_' . $album->slug();
$photos = Cache::get($key);
if (!$photos) {
$photos = array();
$index = 0;
$result = $this->photosets->getPhotos(
array(
'photoset_id' => $album->albumID(),
'extras' => 'url_o,url_q,url_c,url_z,url_m'
)
);
foreach ($result['photoset']['photo'] as $photo) {
$sizes = array(
'thumbnail' => $photo['url_q'],
'fullsize' => $photo['url_o']
$flickr = $this;
return Cache::run(
'FLICKR_PHOTOS_' . $album->slug(),
$this->albumCacheLifetime($album),
function () use ($flickr, $album) {
$photos = array();
$index = 0;
$result = $flickr->photosets->getPhotos(
array(
'photoset_id' => $album->albumID(),
'extras' => 'url_o,url_q,url_c,url_z,url_m'
)
);
foreach (array('c', 'z', 'm', 'o') as $size) {
if (array_key_exists("url_$size", $photo)) {
$sizes['large'] = $photo["url_$size"];
break;
foreach ($result['photoset']['photo'] as $photo) {
$sizes = array(
'thumbnail' => $photo['url_q'],
'fullsize' => $photo['url_o']
);
foreach (array('c', 'z', 'm', 'o') as $size) {
if (array_key_exists("url_$size", $photo)) {
$sizes['large'] = $photo["url_$size"];
break;
}
}
$photos[$index] = new PhotoModel(
$album,
$photo['id'],
$index,
$photo['title'],
$sizes
);
$index++;
}
$photos[$index] = new PhotoModel(
$album,
$photo['id'],
$index,
$photo['title'],
$sizes
);
$index++;
return $photos;
}
Cache::set($key, $photos, $this->albumCacheLifetime($album));
}
return $photos;
);
}

/**
Expand Down Expand Up @@ -161,17 +165,18 @@ private function albumCacheLifetime($album) {
*
* @return string The NSID for the current user.
*/
private function getCurrentUserNSID() {
$key = 'FLICKR_API_NSID_' . $this->_username;
$nsid = Cache::get($key);
if (!$nsid) {
$response = $this->people->findByUsername(
array('username' => $this->_username)
);
$nsid = $response['user']['nsid'];
Cache::set($key, $nsid, 0);
}
return $nsid;
public function getCurrentUserNSID() {
$flickr = $this;
return Cache::run(
'FLICKR_API_NSID_' . $this->_username,
0,
function () use ($flickr) {
$response = $flickr->people->findByUsername(
array('username' => $this->_username)
);
return $response['user']['nsid'];
}
);
}

/**
Expand All @@ -184,21 +189,23 @@ private function getCurrentUserNSID() {
*/
public function request($method, $args=array()) {
$url = $this->constructAPIURL($method, $args);
$key = 'FLICKR_API_REQUEST' . md5($url);
$result = Cache::get($key);
if (!$result) {
$result = JSON::decode($this->_http_client->get($url));
if ($result !== null) {
if ($result['stat'] == 'fail') {
throw new Exception(
$result['message'],
$this->mapErrorCode($method, $result['code'])
);
$flickr = $this;
return Cache::run(
'FLICKR_API_REQUEST' . md5($url),
3600 + rand(0, 300),
function () use ($flickr, $method, $url) {
$result = JSON::decode($flickr->_http_client->get($url));
if ($result !== null) {
if ($result['stat'] == 'fail') {
throw new Exception(
$result['message'],
$flickr->mapErrorCode($method, $result['code'])
);
}
}
Cache::set($key, $result, 3600 + rand(0, 300));
return $result;
}
}
return $result;
);
}

/**
Expand Down Expand Up @@ -249,7 +256,7 @@ private function constructAPIURL($method, $args=array()) {
* @return int The most appropriate HTTP status code or 500 if none can be
* calculated.
*/
private function mapErrorCode($method, $flickr_error_number) {
public function mapErrorCode($method, $flickr_error_number) {
$error_map = array(
'flickr.people.findByUsername' => array(1 => 404, 105 => 503),
'flickr.photosets.getList' => array(1 => 404, 105 => 503),
Expand Down
19 changes: 10 additions & 9 deletions lib/GitHub.php
Expand Up @@ -58,15 +58,16 @@ public function repos() {
* @return array The decoded form of the JSON which was returned.
*/
private function get($path) {
$key = 'GITHUB_API_REQUEST_' . md5($path);
$result = Cache::get($key);
if (!$result) {
$result = JSON::decode(
$this->_http_client->get("https://api.github.com$path")
);
Cache::set($key, $result, 3600 + rand(0, 300));
}
return $result;
$client = $this->_http_client;
return Cache::run(
'GITHUB_API_REQUEST_' . md5($path),
3600 + rand(0, 300),
function () use ($client, $path) {
return JSON::decode(
$client->get("https://api.github.com$path")
);
}
);
}
}

Expand Down
17 changes: 9 additions & 8 deletions lib/SyntaxHighlighter.php
Expand Up @@ -17,14 +17,15 @@ class SyntaxHighlighter {
*/
public static function highlight($matches) {
$key = join('_', array('syntax', $matches[1], md5($matches[2])));
$result = Cache::get($key);
if ($result === null) {
$geshi = new GeSHi(trim($matches[2]), $matches[1]);
$geshi->set_overall_class('codeblock');
$result = $geshi->parse_code();
Cache::set($key, $result, 0);
}
return $result;
return Cache::run(
$key,
0,
function () use ($matches) {
$geshi = new GeSHi(trim($matches[2]), $matches[1]);
$geshi->set_overall_class('codeblock');
return $geshi->parse_code();
}
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion model/BlogEntryModel.php
Expand Up @@ -171,7 +171,7 @@ public function eTag() {
*/
private function html() {
$markdown = file_get_contents($this->_file);
return $this->cache(
return Cache::run(
'blog_html_' . md5($markdown),
0,
function () use ($markdown) {
Expand Down
50 changes: 25 additions & 25 deletions model/FrontPageModel.php
Expand Up @@ -34,36 +34,36 @@ public function link() {
* of data we fetch from.
*/
public function all() {
$key = 'FRONT_PAGE_DATA';
$all = Cache::get($key);
if ($all) {
return $all;
}
$all = array();
return Cache::run(
'FRONT_PAGE_DATA',
$this->ttl(),
function () {
$all = array();

// Mix in the blog
$blog = new BlogModel(null, null, null, null, 1, -1);
foreach ($blog->entries() as $blog_entry) {
$all[$blog_entry->timestamp()] = $blog_entry;
}
// Mix in the blog
$blog = new BlogModel(null, null, null, null, 1, -1);
foreach ($blog->entries() as $blog_entry) {
$all[$blog_entry->timestamp()] = $blog_entry;
}

// Mix in the photo albums
$photos = new PhotosModel(null, 1, -1);
foreach ($photos->albums() as $album) {
$all[$album->timestamp()] = $album;
}
// Mix in the photo albums
$photos = new PhotosModel(null, 1, -1);
foreach ($photos->albums() as $album) {
$all[$album->timestamp()] = $album;
}

// Mix in the photos from Instagram
$instagram = Instagram::getInstance();
foreach ($instagram->getStream() as $photo) {
$all[$photo['timestamp']] = $photo;
}
// Mix in the photos from Instagram
$instagram = Instagram::getInstance();
foreach ($instagram->getStream() as $photo) {
$all[$photo['timestamp']] = $photo;
}

krsort($all);
$all = array_values($all);
Cache::set($key, $all, $this->ttl());
krsort($all);
$all = array_values($all);

return $all;
return $all;
}
);
}

/**
Expand Down
20 changes: 0 additions & 20 deletions model/Model.php
Expand Up @@ -45,26 +45,6 @@ public function newRelicJSHeader() {
public function ttl() {
return 0;
}

/**
* Wrap a chunk of code in some caching.
*
* @param string $key The key for the cache entry.
* @param int $ttl The life time for the cache entry.
* @param callable $callable The code to wrap in caching.
* @param array $args Arguments to pass to the cached function.
*
* @return mixed The result of the wrapped code, possibly from
* the cache.
*/
protected function cache($key, $ttl, $callable, $args = array()) {
$result = Cache::get($key);
if ($result === null) {
$result = call_user_func_array($callable, $args);
Cache::set($key, $result, $ttl);
}
return $result;
}
}

?>

0 comments on commit 832245a

Please sign in to comment.