Fixed some major bugs with implications, cleaning up the cache

expiration process and adding some additional tests.

Cleaned up the unit tests.  They should all run cleanly with rake
test:units now.
This commit is contained in:
albert
2010-10-27 16:56:12 -04:00
parent 484ff696e2
commit 1c9d8c37c7
16 changed files with 214 additions and 104 deletions

View File

@@ -1,9 +1,13 @@
class TagAlias < ActiveRecord::Base
attr_accessor :creator_ip_addr
after_save :update_posts
after_commit :clear_cache
after_commit :clear_remote_cache
validates_presence_of :creator_id, :creator_ip_addr
after_save :clear_cache
after_save :clear_remote_cache
after_save :update_cache
after_destroy :clear_cache
after_destroy :clear_remote_cache
before_validation :initialize_creator, :on => :create
validates_presence_of :creator_id
validates_uniqueness_of :antecedent_name
validate :absence_of_transitive_relation
belongs_to :creator, :class_name => "User"
@@ -21,6 +25,10 @@ class TagAlias < ActiveRecord::Base
alias_hash.values.flatten.uniq
end
def initialize_creator
self.creator_id = CurrentUser.user.id
end
def absence_of_transitive_relation
# We don't want a -> b && b -> c chains
if self.class.exists?(["antecedent_name = ?", consequent_name]) || self.class.exists?(["consequent_name = ?", antecedent_name])
@@ -48,11 +56,9 @@ class TagAlias < ActiveRecord::Base
escaped_antecedent_name = Regexp.escape(antecedent_name)
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{consequent_name} ").strip
CurrentUser.scoped(creator, creator_ip_addr) do
post.update_attributes(
:tag_string => fixed_tags
)
end
post.update_attributes(
:tag_string => fixed_tags
)
end
end
end

View File

@@ -1,19 +1,104 @@
class TagImplication < ActiveRecord::Base
attr_accessor :creator_ip_addr
before_save :clear_cache
before_save :update_descendant_names
after_save :update_descendant_names_for_parent
after_destroy :clear_cache
after_save :update_cache
after_save :update_posts
after_destroy :clear_cache
after_destroy :clear_remote_cache
belongs_to :creator, :class_name => "User"
validates_presence_of :creator_id, :creator_ip_addr
before_validation :initialize_creator, :on => :create
validates_presence_of :creator_id
validates_uniqueness_of :antecedent_name, :scope => :consequent_name
validate :absence_of_circular_relation
def self.with_descendants(names)
Cache.get_multi(names.flatten, "ti") do |name|
([name] + where(["antecedent_name = ?", name]).all.map {|x| x.descendant_names_array}).flatten
end.values.flatten.uniq
module CacheMethods
def clear_cache
Cache.delete("ti:#{Cache.sanitize(antecedent_name)}")
@descendants = nil
end
def clear_remote_cache
Danbooru.config.other_server_hosts.each do |server|
Net::HTTP.delete(URI.parse("http://#{server}/tag_implications/#{id}/cache"))
end
end
def update_cache
descendant_names_array
true
end
end
module DescendantMethods
extend ActiveSupport::Concern
module ClassMethods
def with_descendants(names)
names + Cache.get_multi(names.flatten, "ti") do |name|
([name] + where(["antecedent_name = ?", name]).all.map {|x| x.descendant_names_array}).flatten
end.values.flatten.uniq
end
end
def descendants
@descendants ||= begin
[].tap do |all|
children = [consequent_name]
until children.empty?
all.concat(children)
children = self.class.where(["antecedent_name IN (?)", children]).all.map(&:consequent_name)
end
end
end
end
def descendant_names_array
Cache.get("ti:#{Cache.sanitize(antecedent_name)}") do
descendant_names.split(/ /)
end
end
def update_descendant_names
self.descendant_names = descendants.join(" ")
end
def update_descendant_names!
update_descendant_names
save!
end
def update_descendant_names_for_parent
p = parent
while p
p.update_descendant_names!
p = p.parent
end
end
def clear_descendants_cache
@descendants = nil
end
end
module ParentMethods
def parent
@parent ||= self.class.where(["consequent_name = ?", antecedent_name]).first
end
def clear_parent_cache
@parent = nil
end
end
include CacheMethods
include DescendantMethods
include ParentMethods
def initialize_creator
self.creator_id = CurrentUser.user.id
end
def absence_of_circular_relation
@@ -24,57 +109,13 @@ class TagImplication < ActiveRecord::Base
end
end
def parent
@parent ||= self.class.where(["consequent_name = ?", antecedent_name]).first
end
def descendants
@descendants ||= begin
[].tap do |all|
children = [consequent_name]
until children.empty?
all += children
children = self.class.where(["antecedent_name IN (?)", children]).all.map(&:consequent_name)
end
end
end
end
def descendant_names_array
Cache.get("ti:#{Cache.sanitize(antecedent_name)}") do
descendant_names.split(/ /)
end
end
def update_descendant_names
self.descendant_names = descendants.join(" ")
end
def update_descendant_names!
update_descendant_names
save!
end
def update_descendant_names_for_parent
if parent
parent.update_descendant_names!
end
end
def clear_cache
Cache.delete("ti:#{Cache.sanitize(antecedent_name)}")
end
def update_posts
Post.find_by_tags(antecedent_name).find_each do |post|
escaped_antecedent_name = Regexp.escape(antecedent_name)
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{antecedent_name} #{descendant_names} ").strip
CurrentUser.scoped(creator, creator_ip_addr) do
post.update_attributes(
:tag_string => fixed_tags
)
end
post.update_attributes(
:tag_string => fixed_tags
)
end
end
@@ -83,12 +124,4 @@ class TagImplication < ActiveRecord::Base
clear_parent_cache
clear_descendants_cache
end
def clear_descendants_cache
@descendants = nil
end
def clear_parent_cache
@parent = nil
end
end

View File

@@ -10,6 +10,7 @@ class Upload < ActiveRecord::Base
before_validation :initialize_uploader, :on => :create
before_validation :initialize_status, :on => :create
before_create :convert_cgi_file
after_destroy :delete_temp_file
validate :uploader_is_not_limited
module ValidationMethods
@@ -70,6 +71,8 @@ class Upload < ActiveRecord::Base
end
rescue Exception => x
update_attribute(:status, "error: #{x} - #{x.message}")
ensure
delete_temp_file
end
def convert_to_post
@@ -100,6 +103,10 @@ class Upload < ActiveRecord::Base
end
module FileMethods
def delete_temp_file
FileUtils.rm_f(temp_file_path)
end
def move_file
FileUtils.mv(file_path, md5_file_path)
end
@@ -223,7 +230,7 @@ class Upload < ActiveRecord::Base
end
def temp_file_path
File.join(Rails.root, "tmp", "#{Time.now.to_f}.#{$PROCESS_ID}")
@temp_file_path ||= File.join(Rails.root, "tmp", "#{Time.now.to_f}.#{$PROCESS_ID}")
end
end

View File

@@ -29,14 +29,14 @@ class WikiPage < ActiveRecord::Base
titled(title).select("title, id").first
end
def revert_to(version, reverter_id, reverter_ip_addr)
def revert_to(version)
self.title = version.title
self.body = version.body
self.is_locked = version.is_locked
end
def revert_to!(version, reverter_id, reverter_ip_addr)
revert_to(version, reverter_id, reverter_ip_addr)
def revert_to!(version)
revert_to(version)
save!
end