From 9a96cd9f3bca6f93ed98d6075fd1a9a894041a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Thu, 7 May 2015 01:00:13 +0200 Subject: [PATCH] CRUSHED: duplicate key value violates unique constraint 'index_uploads_on_sha1' --- app/jobs/scheduled/create_missing_avatars.rb | 12 ++++--- app/models/user_avatar.rb | 38 +++++++++++--------- lib/discourse.rb | 2 +- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/app/jobs/scheduled/create_missing_avatars.rb b/app/jobs/scheduled/create_missing_avatars.rb index 42a2b01dc..8526b4115 100644 --- a/app/jobs/scheduled/create_missing_avatars.rb +++ b/app/jobs/scheduled/create_missing_avatars.rb @@ -1,13 +1,15 @@ module Jobs class CreateMissingAvatars < Jobs::Scheduled every 1.hour + def execute(args) - # backfill in batches 5000 an hour - UserAvatar.where(last_gravatar_download_attempt: nil).includes(:user) - .order("users.last_posted_at desc") - .limit(5000).each do |u| + # backfill in batches of 5000 an hour + UserAvatar.includes(:user) + .where(last_gravatar_download_attempt: nil) + .order("users.last_posted_at DESC") + .limit(5000) + .each do |u| u.user.refresh_avatar - u.user.save end end end diff --git a/app/models/user_avatar.rb b/app/models/user_avatar.rb index 73431a961..0a14ec745 100644 --- a/app/models/user_avatar.rb +++ b/app/models/user_avatar.rb @@ -10,27 +10,31 @@ class UserAvatar < ActiveRecord::Base end def update_gravatar! - # special logic for our system user, we do not want the discourse email there - email_hash = user.id == -1 ? User.email_hash("info@discourse.org") : user.email_hash + DistributedMutex.synchronize("update_gravatar_#{user.id}") do + begin + # special logic for our system user + email_hash = user.id == Discourse::SYSTEM_USER_ID ? User.email_hash("info@discourse.org") : user.email_hash - self.last_gravatar_download_attempt = Time.new - gravatar_url = "http://www.gravatar.com/avatar/#{email_hash}.png?s=500&d=404" - tempfile = FileHelper.download(gravatar_url, SiteSetting.max_image_size_kb.kilobytes, "gravatar") + self.last_gravatar_download_attempt = Time.new - upload = Upload.create_for(user.id, tempfile, 'gravatar.png', tempfile.size, { origin: gravatar_url }) + gravatar_url = "http://www.gravatar.com/avatar/#{email_hash}.png?s=500&d=404" + tempfile = FileHelper.download(gravatar_url, SiteSetting.max_image_size_kb.kilobytes, "gravatar") + upload = Upload.create_for(user.id, tempfile, 'gravatar.png', tempfile.size, { origin: gravatar_url }) - if gravatar_upload_id != upload.id - gravatar_upload.try(:destroy!) - self.gravatar_upload = upload - save! + if gravatar_upload_id != upload.id + gravatar_upload.try(:destroy!) + self.gravatar_upload = upload + save! + end + rescue OpenURI::HTTPError + save! + rescue SocketError + # skip saving, we are not connected to the net + Rails.logger.warn "Failed to download gravatar, socket error - user id #{user.id}" + ensure + tempfile.try(:close!) + end end - rescue OpenURI::HTTPError - save! - rescue SocketError - # skip saving, we are not connected to the net - Rails.logger.warn "Failed to download gravatar, socket error - user id #{user.id}" - ensure - tempfile.close! if tempfile && tempfile.respond_to?(:close!) end end diff --git a/lib/discourse.rb b/lib/discourse.rb index 2a139eb2d..845aaf482 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -256,7 +256,7 @@ module Discourse user ||= User.admins.real.order(:id).first end - SYSTEM_USER_ID = -1 unless defined? SYSTEM_USER_ID + SYSTEM_USER_ID ||= -1 def self.system_user User.find_by(id: SYSTEM_USER_ID)