enabled more cache-related code
This commit is contained in:
parent
f3934387cb
commit
799f1d0a5c
@ -120,7 +120,7 @@ class ForumController extends ApplicationController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->forum_post->assignAttributes(array_merge($this->params()->forum_post, ['updater_ip_addr' => $this->request()->remoteIp()]);
|
$this->forum_post->assignAttributes(array_merge($this->params()->forum_post, ['updater_ip_addr' => $this->request()->remoteIp()]));
|
||||||
if ($this->forum_post->save()) {
|
if ($this->forum_post->save()) {
|
||||||
$this->notice("Post updated");
|
$this->notice("Post updated");
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ class Comment extends Rails\ActiveRecord\Base
|
|||||||
{
|
{
|
||||||
$source_lang_list = implode(',', $source_langs);
|
$source_lang_list = implode(',', $source_langs);
|
||||||
$key = "comment:" . $this->id . ":" . strtotime($this->updated_at) . ":" . $target_lang . ":" . $source_lang_list;
|
$key = "comment:" . $this->id . ":" . strtotime($this->updated_at) . ":" . $target_lang . ":" . $source_lang_list;
|
||||||
# TODO
|
|
||||||
// return Rails::cache()->fetch($key) {
|
return Rails::cache()->fetch($key, function() use ($target_lang, $source_langs) {
|
||||||
return $this->get_translated_formatted_body_uncached($target_lang, $source_langs);
|
return $this->get_translated_formatted_body_uncached($target_lang, $source_langs);
|
||||||
// }
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function author()
|
public function author()
|
||||||
|
@ -21,21 +21,21 @@ class FlaggedPostDetail extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
static public function new_deleted_posts($user)
|
static public function new_deleted_posts($user)
|
||||||
{
|
{
|
||||||
if ($user->is_anonymous())
|
if ($user->is_anonymous()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Rails::cache()->fetch(
|
||||||
|
'deleted_posts:'.$user->id.':'.$user->last_deleted_post_seen_at,
|
||||||
|
['expires_in' => '1 minute'],
|
||||||
|
function() use ($user) {
|
||||||
return self::connection()->selectValue(
|
return self::connection()->selectValue(
|
||||||
"SELECT COUNT(*) FROM flagged_post_details fpd JOIN posts p ON (p.id = fpd.post_id) " .
|
"SELECT COUNT(*) FROM flagged_post_details fpd JOIN posts p ON (p.id = fpd.post_id) " .
|
||||||
"WHERE p.status = 'deleted' AND p.user_id = ? AND fpd.user_id <> ? AND fpd.created_at > ?",
|
"WHERE p.status = 'deleted' AND p.user_id = ? AND fpd.user_id <> ? AND fpd.created_at > ?",
|
||||||
$user->id, $user->id, $user->last_deleted_post_seen_at
|
$user->id, $user->id, $user->last_deleted_post_seen_at
|
||||||
);
|
);
|
||||||
# iTODO:
|
}
|
||||||
// return Rails.cache.fetch("deleted_posts:#{user.id}:#{user.last_deleted_post_seen_at.to_i}", :expires_in => 1.minute) do
|
);
|
||||||
// select_value_sql(
|
|
||||||
// "SELECT COUNT(*) FROM flagged_post_details fpd JOIN posts p ON (p.id = fpd.post_id) " +
|
|
||||||
// "WHERE p.status = 'deleted' AND p.user_id = ? AND fpd.user_id <> ? AND fpd.created_at > ?",
|
|
||||||
// user.id, user.id, user.last_deleted_post_seen_at).to_i
|
|
||||||
// end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX: author and flagged_by are redundant
|
# XXX: author and flagged_by are redundant
|
||||||
|
@ -18,7 +18,7 @@ class ForumPost extends Rails\ActiveRecord\Base
|
|||||||
protected function callbacks()
|
protected function callbacks()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'after_create' => ['initialize_last_updated_by', 'update_parent_on_create'],
|
'after_create' => ['initialize_last_updated_by', 'update_parent_on_create', 'clear_cache'],
|
||||||
'before_destroy' => ['update_parent_on_destroy'],
|
'before_destroy' => ['update_parent_on_destroy'],
|
||||||
'before_validation' => ['validate_title', 'validate_lock']
|
'before_validation' => ['validate_title', 'validate_lock']
|
||||||
];
|
];
|
||||||
@ -180,4 +180,9 @@ class ForumPost extends Rails\ActiveRecord\Base
|
|||||||
{
|
{
|
||||||
return $this->creator->name;
|
return $this->creator->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function clear_cache()
|
||||||
|
{
|
||||||
|
Rails::cache()->delete("forum_posts");
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,25 +5,30 @@ trait PostCountMethods
|
|||||||
{
|
{
|
||||||
# A small sanitation
|
# A small sanitation
|
||||||
$tags = preg_replace('/ +/', ' ', trim($tags));
|
$tags = preg_replace('/ +/', ' ', trim($tags));
|
||||||
|
$cache_version = (int)Rails::cache()->read('$cache_version');
|
||||||
|
# iTODO: cache hash key
|
||||||
|
$key = 'post_count.' . $tags . ':' . 'v.' . $cache_version;
|
||||||
|
|
||||||
# No cache. This query is too slow, if no tags, just return row_count().
|
$count = (int)Rails::cache()->fetch($key, function() use ($tags) {
|
||||||
if (!$tags) {
|
list($sql, $params) = Post::generate_sql($tags, ['count' => true]);
|
||||||
return self::row_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cache_version = Rails.cache.read("$cache_version").to_i
|
|
||||||
# Use base64 encoding of tags query for memcache key
|
|
||||||
// tags_base64 = Base64.urlsafe_encode64(tags)
|
|
||||||
// key = "post-count/v=#{cache_version}/#{tags_base64}"
|
|
||||||
|
|
||||||
// count = Rails.cache.fetch(key) {
|
|
||||||
// Post.count_by_sql(Post.generate_sql(tags, :count => true))
|
|
||||||
// }.to_i
|
|
||||||
list($sql, $params) = Post::generate_sql($tags, array('count' => true));
|
|
||||||
// vde($sql);
|
|
||||||
array_unshift($params, $sql);
|
array_unshift($params, $sql);
|
||||||
|
|
||||||
return Post::countBySql($params);
|
return Post::countBySql($params);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
|
||||||
|
# This is just too brittle, and hard to make work with other features that may
|
||||||
|
# hide posts from the index.
|
||||||
|
# if tags.blank?
|
||||||
|
# return select_value_sql("SELECT row_count FROM table_data WHERE name = 'posts'").to_i
|
||||||
|
# else
|
||||||
|
# c = select_value_sql("SELECT post_count FROM tags WHERE name = ?", tags).to_i
|
||||||
|
# if c == 0
|
||||||
|
# return Post.count_by_sql(Post.generate_sql(tags, :count => true))
|
||||||
|
# else
|
||||||
|
# return c
|
||||||
|
# end
|
||||||
|
# end
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function recalculate_row_count()
|
static public function recalculate_row_count()
|
||||||
|
@ -315,9 +315,9 @@ class Tag extends Rails\ActiveRecord\Base
|
|||||||
#
|
#
|
||||||
# === Parameters
|
# === Parameters
|
||||||
# * :tag_name<String>:: The tag name to search for
|
# * :tag_name<String>:: The tag name to search for
|
||||||
# TODO
|
|
||||||
static public function type_name($tag_name)
|
static public function type_name($tag_name)
|
||||||
{
|
{
|
||||||
|
# iTODO: hash key
|
||||||
return Rails::cache()->fetch('tag_type.' . $tag_name, ['expires_in' => '1 day'], function() use ($tag_name) {
|
return Rails::cache()->fetch('tag_type.' . $tag_name, ['expires_in' => '1 day'], function() use ($tag_name) {
|
||||||
return self::type_name_helper(str_replace(' ', '_', $tag_name));
|
return self::type_name_helper(str_replace(' ', '_', $tag_name));
|
||||||
});
|
});
|
||||||
@ -362,29 +362,29 @@ class Tag extends Rails\ActiveRecord\Base
|
|||||||
# Get all tag types for the given tags.
|
# Get all tag types for the given tags.
|
||||||
static public function batch_get_tag_types($post_tags)
|
static public function batch_get_tag_types($post_tags)
|
||||||
{
|
{
|
||||||
$types = [];
|
$post_tags_key = [];
|
||||||
foreach ($post_tags as $tag) {
|
|
||||||
$types[$tag] = self::type_name($tag);
|
foreach ($post_tags as $t) {
|
||||||
|
# iTODO: hash keys.
|
||||||
|
$post_tags_key[] = 'tag_type.' . $t;
|
||||||
}
|
}
|
||||||
return $types;
|
# Without this, the following splat will eat the last argument because
|
||||||
|
# it'll be considered an option instead of key (being a hash).
|
||||||
|
$post_tags_key[] = [];
|
||||||
|
|
||||||
// $post_tags = Set.new(post_tags)
|
$results = [];
|
||||||
|
$cached = call_user_func_array([Rails::cache(), 'readMulti'], $post_tags_key);
|
||||||
// post_tags_key = post_tags.each_with_object([]) { |t, k| k << { :tag_type => t } }
|
foreach ($cached as $cache_key => $value) {
|
||||||
// # Without this, the following splat will eat the last argument because
|
# The if cache_key is required since there's small chance read_multi
|
||||||
// # it'll be considered an option instead of key (being a hash).
|
# returning nil key on certain key names.
|
||||||
// post_tags_key << {}
|
// if ($cache_key) {
|
||||||
|
$results[substr($cache_key, 9)] = $value;
|
||||||
// results = {}
|
// }
|
||||||
// Rails.cache.read_multi(*post_tags_key).each do |cache_key, value|
|
}
|
||||||
// # The if cache_key is required since there's small chance read_multi
|
foreach( array_diff( $post_tags, array_keys($results) ) as $tag ) {
|
||||||
// # returning nil key on certain key names.
|
$results[$tag] = self::type_name($tag);
|
||||||
// results[cache_key[:tag_type]] = value if cache_key
|
}
|
||||||
// end
|
return $results;
|
||||||
// (post_tags - results.keys).each do |tag|
|
|
||||||
// results[tag] = type_name(tag)
|
|
||||||
// end
|
|
||||||
// return results
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns tags (with type specified by input) related by input tag
|
# Returns tags (with type specified by input) related by input tag
|
||||||
@ -414,15 +414,6 @@ class Tag extends Rails\ActiveRecord\Base
|
|||||||
$reduced[] = ['name' => $row['name'], 'post_count' => $row['post_count']];
|
$reduced[] = ['name' => $row['name'], 'post_count' => $row['post_count']];
|
||||||
}
|
}
|
||||||
return $reduced;
|
return $reduced;
|
||||||
|
|
||||||
// return Post::select('posts.*, tags.name AS tag_name, tags.post_count AS tag_post_count')
|
|
||||||
// ->joins('JOIN posts_tags pt ON posts.id = pt.post_id JOIN tags ON pt.tag_id = tags.id')
|
|
||||||
// ->where('posts.status <> "deleted"')->where('tags.name IN (?)', $tag)
|
|
||||||
// ->where('tags.tag_type = ?', $type)->group('tags.name')->limit($limit)
|
|
||||||
// ->take()->reduce([], function($result, $hash) {
|
|
||||||
// $result[] = ['name' => $hash->tag_name, 'post_count' => $hash->tag_post_count];
|
|
||||||
// return $result;
|
|
||||||
// });
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +456,7 @@ class Tag extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
!is_array($tags) && $tags = array($tags);
|
!is_array($tags) && $tags = array($tags);
|
||||||
|
|
||||||
|
# iTODO: hash key
|
||||||
return Rails::cache()->fetch('category.reltags.tags.' . implode(',', $tags), ['expires_in' => '1 hour'], function() use ($tags) {
|
return Rails::cache()->fetch('category.reltags.tags.' . implode(',', $tags), ['expires_in' => '1 hour'], function() use ($tags) {
|
||||||
$from = array("posts_tags pt0");
|
$from = array("posts_tags pt0");
|
||||||
$cond = array("pt0.post_id = pt1.post_id");
|
$cond = array("pt0.post_id = pt1.post_id");
|
||||||
@ -507,6 +499,13 @@ class Tag extends Rails\ActiveRecord\Base
|
|||||||
return Rails::cache()->fetch('$tag_version', function() { return 0; });
|
return Rails::cache()->fetch('$tag_version', function() { return 0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Create a compact list of all active tags, sorted by post_count.
|
||||||
|
#
|
||||||
|
# "1`tagme` 2`fixme` 3`fixed`alias` "
|
||||||
|
#
|
||||||
|
# Each tag is bounded by backticks, so "`tagme`" can be used to match a whole tag.
|
||||||
|
#
|
||||||
|
# This is returned as a preencoded JSON string, so the entire block can be cached.
|
||||||
static public function get_json_summary()
|
static public function get_json_summary()
|
||||||
{
|
{
|
||||||
$summary_version = self::get_summary_version();
|
$summary_version = self::get_summary_version();
|
||||||
|
@ -51,21 +51,20 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
public function log($ip)
|
public function log($ip)
|
||||||
{
|
{
|
||||||
// Rails.cache.fetch({ 'type' => :user_logs, 'id' => self.id, 'ip' => ip }, 'expires_in' => 10.minutes) do
|
# iTODO: UserLog doesn't exist yet.
|
||||||
// Rails.cache.fetch({ 'type' => :user_logs, 'id' => :all }, 'expires_id' => 1.day) do
|
return;
|
||||||
// UserLog.where('created_at < ?', 3.days.ago).delete_all
|
|
||||||
// end
|
# iTODO: hash key
|
||||||
// begin
|
Rails::cache()->fetch('type.user_logs;id.'.$this->id.';ip.'.$ip, ['expires_in' => '10 minutes'], function() use ($ip) {
|
||||||
// log_entry = self.user_logs.find_or_initialize_by_ip_addr('ip_addr' => ip)
|
# iTODO: hash key
|
||||||
// log_entry.created_at = Time.now
|
Rails::cache()->fetch('type.user_logs;id.all', ['expires_in' => '1 day'], function() {
|
||||||
// log_entry.save
|
return UserLog::where('created_at < ?', date('Y-m-d 0:0:0', strtotime('-3 days')))->deleteAll();
|
||||||
// # Once in a blue moon there will be race condition on find_or_initialize
|
});
|
||||||
// # resulting unique key constraint violation.
|
|
||||||
// # It doesn't really affect anything so just ignore that error.
|
$log_entry = UserLog::where(['ip_addr' => $ip])->firstOrInitialize();
|
||||||
// rescue ActiveRecord::RecordNotUnique
|
$log_entry->created_at = date('Y-m-d H:i:s');
|
||||||
// true
|
$log_entry->save();
|
||||||
// end
|
});
|
||||||
// end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# UserBlacklistMethods {
|
# UserBlacklistMethods {
|
||||||
@ -200,10 +199,13 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
static public function find_name($user_id)
|
static public function find_name($user_id)
|
||||||
{
|
{
|
||||||
# iTODO:
|
Rails::cache()->fetch('user_name:' . $user_id, function() use ($user_id) {
|
||||||
// return Rails.cache.fetch("user_name:#{user_id}") do
|
try {
|
||||||
return self::_find_name_helper($user_id);
|
return self::find($user_id)->name;
|
||||||
// end
|
} catch (Rails\ActiveRecord\Exception\RecordNotFoundException $e) {
|
||||||
|
return CONFIG()->default_guest_name;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function find_by_name($name)
|
static public function find_by_name($name)
|
||||||
@ -221,10 +223,9 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
# iTODO:
|
protected function update_cached_name()
|
||||||
protected function _update_cached_name()
|
|
||||||
{
|
{
|
||||||
// Rails::cache()->write("user_name:".$this->id, $this->name);
|
Rails::cache()->write("user_name:".$this->id, $this->name);
|
||||||
}
|
}
|
||||||
# }
|
# }
|
||||||
|
|
||||||
@ -269,17 +270,19 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
{
|
{
|
||||||
$type = !empty($options['type']) ? $options['type'] : null;
|
$type = !empty($options['type']) ? $options['type'] : null;
|
||||||
|
|
||||||
// uploaded_tags = Rails.cache.read("uploaded_tags/#{id}/#{type}")
|
$uploaded_tags = Rails::cache()->read("uploaded_tags/". $this->id . "/" . $type);
|
||||||
// return uploaded_tags unless uploaded_tags == nil
|
if ($uploaded_tags) {
|
||||||
|
return $uploaded_tags;
|
||||||
|
}
|
||||||
|
|
||||||
// if ((Rails.env == "test") == "test") {
|
if (Rails::env() == "test") {
|
||||||
// # disable filtering in test mode to simplify tests
|
# disable filtering in test mode to simplify tests
|
||||||
// popular_tags = ""
|
$popular_tags = "";
|
||||||
// } else {
|
} else {
|
||||||
$popular_tags = implode(', ', self::connection()->selectValues("SELECT id FROM tags WHERE tag_type = " . CONFIG()->tag_types['General'] . " ORDER BY post_count DESC LIMIT 8"));
|
$popular_tags = implode(', ', self::connection()->selectValues("SELECT id FROM tags WHERE tag_type = " . CONFIG()->tag_types['General'] . " ORDER BY post_count DESC LIMIT 8"));
|
||||||
if ($popular_tags)
|
if ($popular_tags)
|
||||||
$popular_tags = "AND pt.tag_id NOT IN (${popular_tags})";
|
$popular_tags = "AND pt.tag_id NOT IN (${popular_tags})";
|
||||||
// }
|
}
|
||||||
|
|
||||||
if ($type) {
|
if ($type) {
|
||||||
$type = (int)$type;
|
$type = (int)$type;
|
||||||
@ -310,28 +313,28 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
$uploaded_tags = self::connection()->select($sql);
|
$uploaded_tags = self::connection()->select($sql);
|
||||||
|
|
||||||
// Rails.cache.write("uploaded_tags/#{id}/#{type}", uploaded_tags, 'expires_in' => 1.day)
|
Rails::cache()->write("uploaded_tags/" . $this->id . "/" . $type, $uploaded_tags, ['expires_in' => '1 day']);
|
||||||
|
|
||||||
return $uploaded_tags;
|
return $uploaded_tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
# iTODO:
|
|
||||||
public function voted_tags(array $options = array())
|
public function voted_tags(array $options = array())
|
||||||
{
|
{
|
||||||
$type = !empty($options['type']) ? $options['type'] : null;
|
$type = !empty($options['type']) ? $options['type'] : null;
|
||||||
|
|
||||||
// $favorite_tags = Rails.cache.read("favorite_tags/#{id}/#{type}")
|
$favorite_tags = Rails::cache()->read("favorite_tags/". $this->id . "/" . $type);
|
||||||
// if ($favorite_tags != nil)
|
if ($favorite_tags) {
|
||||||
// return $favorite_tags;
|
return $favorite_tags;
|
||||||
|
}
|
||||||
|
|
||||||
// if (Rails.env == "test") {
|
if (Rails::env() == "test") {
|
||||||
// # disable filtering in test mode to simplify tests
|
# disable filtering in test mode to simplify tests
|
||||||
// popular_tags = ""
|
$popular_tags = "";
|
||||||
// } else {
|
} else {
|
||||||
$popular_tags = implode(', ', self::connection()->selectValues("SELECT id FROM tags WHERE tag_type = " . CONFIG()->tag_types['General'] . " ORDER BY post_count DESC LIMIT 8"));
|
$popular_tags = implode(', ', self::connection()->selectValues("SELECT id FROM tags WHERE tag_type = " . CONFIG()->tag_types['General'] . " ORDER BY post_count DESC LIMIT 8"));
|
||||||
if ($popular_tags)
|
if ($popular_tags)
|
||||||
$popular_tags = "AND pt.tag_id NOT IN (${popular_tags})";
|
$popular_tags = "AND pt.tag_id NOT IN (${popular_tags})";
|
||||||
// }
|
}
|
||||||
|
|
||||||
if ($type) {
|
if ($type) {
|
||||||
$type = (int)$type;
|
$type = (int)$type;
|
||||||
@ -362,7 +365,7 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
|
|
||||||
$favorite_tags = self::connection()->select($sql);
|
$favorite_tags = self::connection()->select($sql);
|
||||||
|
|
||||||
// Rails.cache.write("favorite_tags/#{id}/#{type}", favorite_tags, 'expires_in' => 1.day)
|
Rails::cache()->write("favorite_tags/" . $this->id . "/" . $type, $favorite_tags, ['expires_in' => '1 day']);
|
||||||
|
|
||||||
return $favorite_tags;
|
return $favorite_tags;
|
||||||
}
|
}
|
||||||
@ -392,16 +395,14 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
return $this->post_count;
|
return $this->post_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
# iTODO:
|
|
||||||
public function held_post_count()
|
public function held_post_count()
|
||||||
{
|
{
|
||||||
return Post::where("user_id = ? AND is_held AND status <> 'deleted'", $this->id)->count();
|
$version = (int)Rails::cache()->read('$cache_version');
|
||||||
// $version = (int)Rails::cache()->read("%cache_version");
|
$key = 'held-post-count/v=' . $version . '/u=' . $this->id;
|
||||||
// $key = "held-post-count/v=".$version."/u=".$this->id;
|
|
||||||
|
|
||||||
// return Rails::cache()->fetch($key) {
|
return Rails::cache()->fetch($key, function() {
|
||||||
// Post::count(['conditions' => ["user_id = ? AND is_held AND status <> 'deleted'", $this->id]]);
|
return Post::where(['user_id' => $this->id, 'is_held' => true])->where('status <> ?', 'deleted')->count();
|
||||||
// }
|
});
|
||||||
}
|
}
|
||||||
# }
|
# }
|
||||||
|
|
||||||
@ -794,7 +795,7 @@ class User extends Rails\ActiveRecord\Base
|
|||||||
'before_create' => $before_create,
|
'before_create' => $before_create,
|
||||||
'before_save' => array('_encrypt_password'),
|
'before_save' => array('_encrypt_password'),
|
||||||
'before_validation' => array('_commit_secondary_languages'),
|
'before_validation' => array('_commit_secondary_languages'),
|
||||||
'after_save' => array('_commit_blacklists', '_update_cached_name'),
|
'after_save' => array('_commit_blacklists', 'update_cached_name'),
|
||||||
'after_create' => array('_set_default_blacklisted_tags', '_increment_count'),
|
'after_create' => array('_set_default_blacklisted_tags', '_increment_count'),
|
||||||
'after_destroy' => array('_decrement_count')
|
'after_destroy' => array('_decrement_count')
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user