After our migration (back) to Amazon S3, we appear to have quite a few images where the optimized versions are missing, but the full-size ones are there (example).
There is a Rake task for regenerating optimized images, but it only appears to work with local storage. How would I do this with remote images?
I’m afraid you’ll have to write your own rake task for that. Here’s some pseudo code on how I’d start
FOR EACH oi IN optimized_images
IF file_exists_on_s3?(oi.upload.url) AND NOT file_exists_on_s3?(oi.url) THEN
OptimizedImage.create_for(oi.upload, oi.width, oi.height)
END IF
END FOR
I just migrated to S3, and indeed the /optimized/ folder is not transferred in the migration. I’d like to get rid of the /optimized/ folder, as it adds significant weight to my daily backup.
فريق العمل، لقد علقت في موقف يتعلق بـ الصورة الشخصية وأهدرت حوالي 6 ساعات من وقتي لكنني وجدت الحل المثالي، لذا سأشاركه هنا.
التخزين: استخدام AWS S3 مع CDN في المقدمة.
المشكلة 1: كنت قادرًا على رفع الصورة الشخصية من منطقة تغيير الصورة الشخصية، لكنها لم تظهر في الملف الشخصي. قمت بتحديث كودي إلى أحدث إصدار من Discourse وبدأت الصورة الشخصية بالظهور في واجهة المستخدم
الكود القديم - لم يكن يعرض الصورة الشخصية
module FileStore
class S3Store < BaseStore
...
def path_for(upload)
url = upload&.url
if url && url[/^\/[^\/]/]
FileStore::LocalStore.new.path_for(upload)
else
url
end
end
...
end
end
الحل: أحدث كود - بدأ في عرض الصورة الشخصية للرفع الجديد
module FileStore
class S3Store < BaseStore
...
def path_for(upload)
url = upload&.url
FileStore::LocalStore.new.path_for(upload) if url && url[/^\/[^\/]/]
end
...
end
end
ملاحظة: أرجوكم، أيها الأصدقاء، حافظوا على تحديث كودكم الخاص مع Discourse upstream بشكل منتظم، فهذا سيحافظ على تحديث كودنا مع إصلاحات الأمان وسيجعله خاليًا من الأخطاء.
المشكلة 2: أنا وفريقي حاولنا تغيير الصور الشخصية قبل إصلاح الخطأ المذكور أعلاه في المشكلة 1. وقد أدى ذلك إلى إنشاء العديد من الإدخالات في جدول uploads بقيمة unknown في عمود extension. لم يكن الكود يعالج الصورة الشخصية بشكل صحيح في عملية تحسين الصور (النموذج: OptimizedImage) بسبب مسار ملف S3 الخاطئ.
لذلك، وجدت أيضًا حلاً بديلاً لإصلاح هذه النوعية من الإدخالات التي حدثت قبل إصلاح كودي.
الحل
متعدد المواقع
يمكننا تشغيل الكود أدناه مباشرة في وحدة تحكم Rails في الإنتاج - أو باستخدام مهمة rake.
RailsMultisite::ConnectionManagement.each_connection do |db|
Upload.where(extension: "unknown").each do |upload|
upload.update(extension: File.extname(upload.url).gsub(".",""))
end
OptimizedImage.destroy_all
UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id;
Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }
end
عادي - موقع واحد
يمكننا تشغيل الكود أدناه مباشرة في وحدة تحكم Rails في الإنتاج - أو باستخدام مهمة rake.
Upload.where(extension: "unknown").each do |upload|
upload.update(extension: File.extname(upload.url).gsub(".",""))
end
OptimizedImage.destroy_all
UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id;
Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }
لذا قمت بتجربة الأمر (السطر الثاني فقط)، لكنه لا يبدو أنه يعمل. فقد أعاد الكثير من السجلات مثل:
id: 1234,
user_id: 1234,
custom_upload_id: nil,
gravatar_upload_id: nil,
last_gravatar_download_attempt: Thu, 07 May 2015 09:40:35 UTC +00:00,
created_at: Thu, 07 May 2015 09:40:35 UTC +00:00,
updated_at: Thu, 07 May 2015 09:40:36 UTC +00:00>,
وجدت سجلًا واحدًا يحتوي على custom_upload_id مُعيينًا إلى معرف، واستخدمت الأمر التالي للعثور على ملف المستخدم الشخصي: User.find_by(id: 123456)
لكن عند عرض ملفه الشخصي، لا يزال الرمز الظاهر فارغًا. كما يمكنني رؤية أنه لم يتم رفع أي ملفات جديدة إلى S3 مؤخرًا (لا يوجد أي ملف خلال آخر 6 ساعات). لذا أعتقد أن الصور المحسّنة لم يتم إنشاؤها نتيجة لذلك.
الخبر الجيد هو أنه عند البحث عن صورة رمزية عبر أمر rails:
تبدو السجلات صحيحة، وروابط S3 التي تحققت منها حتى الآن تعمل جميعها. وتبدو السجلات متسقة مع مثيل آخر استخدم S3 منذ البداية.
ثم عند استخدام: OptimizedImage.where(upload_id: upload_id).where(version: 2)
في المثيل السابق، أرى مجموعة من الصور المحسّنة. لكن في المثيل الجديد، لا توجد أي سجلات. وهذا يبدو صحيحًا. بالنسبة للمستخدم الذي تم تعيين custom_upload_id له، يبدو أن هناك صورًا محسّنة له على S3، لكن تلك السجلات تعود إلى أيام مضت.
إذًا يبدو أنني بحاجة فقط إلى إيجاد طريقة لتحفيز إنشاء صور الرموز المحسّنة.
المثيل الجديد يعمل حاليًا في وضع القراءة فقط، ولا أعرف ما إذا كان هذا عاملًا مؤثرًا. فقد نجح إعادة بناء المنشورات بشكل جيد في وضع القراءة فقط.
تعديل: أرى العديد من الوظائف في sidekiq لإنشاء صور رمزية مصغرة
لذا ربما أحتاج فقط إلى الخروج من وضع القراءة فقط للسماح بمعالجتها. سأقوم بتحديث النتيجة لاحقًا.
إذن أرى أن مهمة Jobs::CreateAvatarThumbnails تُنفَّذ عبر Sidekiq. لكن لم يتم تحميل أي شيء إلى سلة S3 منذ 9 ساعات. لذا لا أعرف ما الذي يُستدل منه على ذلك.