2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-05 08:59:27 +08:00

PERF: reduce storage requirements for incoming links

Only store incoming links for topics.
This commit is contained in:
Sam 2014-08-04 11:06:06 +10:00
parent b36273e4ac
commit 0920c4bea6
8 changed files with 129 additions and 120 deletions

View file

@ -2,38 +2,50 @@ class IncomingLink < ActiveRecord::Base
belongs_to :topic
belongs_to :user
validates :url, presence: true
validate :referer_valid
validate :post_id, presence: true
before_validation :extract_domain
before_validation :extract_topic_and_post
after_create :update_link_counts
def self.add(request,current_user=nil)
user_id, host, referer = nil
attr_accessor :url
if request['u']
u = User.select(:id).find_by(username_lower: request["u"].downcase)
def self.add(opts)
user_id, host, referer = nil
current_user = opts[:current_user]
if username = opts[:username]
u = User.select(:id).find_by(username_lower: username.downcase)
user_id = u.id if u
end
if request.referer.present?
if opts[:referer].present?
begin
host = URI.parse(request.referer).host
referer = request.referer[0..999]
host = URI.parse(opts[:referer]).host
referer = opts[:referer][0..999]
rescue URI::InvalidURIError
# bad uri, skip
end
end
if host != request.host && (user_id || referer)
if host != opts[:host] && (user_id || referer)
post_id = opts[:post_id]
post_id ||= Post.where(topic_id: opts[:topic_id],
post_number: opts[:post_number] || 1)
.pluck(:id).first
cid = current_user ? (current_user.id) : (nil)
unless cid && cid == user_id
IncomingLink.create(url: request.url,
referer: referer,
IncomingLink.create(referer: referer,
user_id: user_id,
post_id: post_id,
current_user_id: cid,
ip_address: request.remote_ip)
ip_address: opts[:ip_address]) if post_id
end
end
@ -49,35 +61,14 @@ class IncomingLink < ActiveRecord::Base
end
end
# Internal: If link is internal and points to topic/post, extract their IDs.
def extract_topic_and_post
if url.present?
parsed = URI.parse(url)
begin
# TODO achieve same thing with no exception
params = Rails.application.routes.recognize_path(parsed.path)
if self.topic_id = params[:topic_id]
self.post_number = params[:post_number] || 1
end
rescue ActionController::RoutingError
# If we can't route to the url, that's OK. Don't save those two fields.
end
end
end
# Internal: Update appropriate link counts.
def update_link_counts
if topic_id.present?
exec_sql("UPDATE topics
SET incoming_link_count = incoming_link_count + 1
WHERE id = ?", topic_id)
if post_number.present?
exec_sql("UPDATE posts
SET incoming_link_count = incoming_link_count + 1
WHERE topic_id = ? and post_number = ?", topic_id, post_number)
end
end
exec_sql("UPDATE topics
SET incoming_link_count = incoming_link_count + 1
WHERE id = (SELECT topic_id FROM posts where id = ?)", post_id)
exec_sql("UPDATE posts
SET incoming_link_count = incoming_link_count + 1
WHERE id = ?", post_id)
end
protected