روابط التحميلات المعطلة في المواضيع تؤدي إلى أخطاء 500 مع 2.5.0

أدير موقع Discourse وأود أن أبدأ بالقول كم أحب هذا البرنامج. شكرًا لفريق العمل على الجهد الرائع، فهذا أداة رائعة.

بعد ترقية إلى الإصدار 2.5.0، واجهتُ مشاكل كبيرة. إليك ملخصًا للحل الذي اعتمدته. ربما يؤدي ذلك إلى إصلاح أفضل في الإصدارات المستقبلية.

بعض المواضيع الموجودة في قاعدة بياناتنا تحتوي على ملفات مرفقة تالفة. كنا نستخدم ميزة “رفع الملفات عبر S3” وحذفنا الـ bucket بالخطأ. نعم، هذا أمر غبي جدًا، لكننا فعلناه! النتيجة كانت فقدان جميع صور المواضيع.

إلا أنه باستثناء فقدان العديد من الصور، كان كل شيء على ما يرام، حيث أظهر Discourse روابط معطلة لصور غير موجودة، لكن الموقع كان يعمل بشكل جيد.

لكن عندما أردنا الترقية إلى الإصدار 2.5.0، بدأ كل شيء في الاختلال: تلقى جميع المستخدمين المسجلين أخطاءً من نوع 500، بينما استطاع الزوار المجهولون رؤية الموقع.

بعد التحقيق، أدركت أن Discourse كان يفشل بسبب أخطاء من نوع “الملف غير موجود”. يبدو أنه كان يحاول تنزيلها. اضطررتُ إلى إجبار دالة local? على أن تكون true في الملف /var/www/discourse/app/models/upload.rb، وقد نجح ذلك، لكنني قلق قليلاً بشأن الترقيات القادمة…

هذا بالتأكيد شيء جديد، إذ لم تتعطل الترقيات السابقة.

على سبيل المثال، هل توجد طريقة يمكنني اتباعها لحذف جميع روابط الصور الميتة الموجودة في مواضيعنا؟

شكرًا لك.

حصلنا على السلوك المعاكس: المستخدم المسجل الدخول يعمل بشكل جيد، بينما غير المسجلين غير قادرين على الاتصال ويحصلون على خطأ 500

هل يمكنك مشاركة تتبع كامل (backtrace) لإحدى هذه الأخطاء؟
تحقق من صفحة /logs الخاصة بك.

يبدو لي هذا تمامًا وكأنه إضافة غير متوافقة. ما هي الإضافات غير الرسمية التي تعمل بها؟ هل جربت إعادة البناء بدونها؟

بالتأكيد، في ملف log/production.log الخاص بي، ظهرت الاستثناء التالي (عندما كان Discourse يحاول الوصول إلى حاوية S3 الفارغة (والتي قمت بإعادة إنشائها، على أمل أن يحل ذلك المشكلة).

Started GET “/” for 86.246.127.170 at 2020-05-16 14:29:06 +0000
Processing by ListController#latest as HTML
Creating scope :open. Overwriting existing method Poll.open.
Completed 500 Internal Server Error in 3638ms (ActiveRecord: 0.0ms | Allocations: 135090)
NoMethodError (undefined method path' for nil:NilClass) /var/www/discourse/lib/file_store/base_store.rb:150:in cache_file’

آمل أن يكون ذلك مفيدًا.

شكرًا، قد يكون هذا هو السبب. لدي بالفعل إضافتان مثبتتان: Discourse Adsense و discourse-chat-integration. سأحاول إعادة البناء بدونهما.

يمكنني تأكيد أن هذا ليس ناتجًا عن إضافة: لقد قمت بتكرار نفس الخطأ مع تثبيت جديد + استعادة لنسخة احتياطية أخيرة وبدون أي إضافات مثبتة ما عدا docker_manager.

أول تتبع للمكدس الذي حصلت عليه هو:

اكتمل خطأ 500 في الخادم الداخلي في 4169 مللي ثانية (ActiveRecord: 0.0 مللي ثانية | التخصيصات: 72058)
NoMethodError (طريقة غير معرفة path' لـ nil:NilClass) /var/www/discourse/lib/file_store/base_store.rb:150:in cache_file’

قمت بتطبيق التصحيح بهذه الطريقة:

def cache_file(file, filename)
path = get_cache_path_for(filename)
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)

  if file.nil?
    return
  end

  FileUtils.cp(file.path, path)

مما أدى إلى خطأ ثانٍ (الذي ذكرته في منشوري الأول):

بدأ GET “/” من 86.246.127.170 في 2020-05-18 07:37:40 +0000
معالجة بواسطة CategoriesController#index بصيغة HTML
اكتمل خطأ 500 في الخادم الداخلي في 4342 مللي ثانية (ActiveRecord: 0.0 مللي ثانية | التخصيصات: 60478)
NoMethodError (طريقة غير معرفة path' لـ nil:NilClass) /var/www/discourse/app/models/upload.rb:193:in fix_dimensions!’

والذي قمت بإصلاحه بإجبار local؟ على أن تكون true:

def local?
return true
!(url =~ /^(https?:)?///)
end

هل قمت بنقل ملفاتك من أو إلى S3 في أي وقت مضى؟

نعم، فعلتُ ذلك. لكن بعد ذلك، تم حذف الدلو. وعُدتُ إلى التخزين المحلي (مع وجود روابط صور غير صالحة في المواضيع السابقة، بطبيعة الحال).

أعتقد أن أفضل حل هنا هو حذف جميع صفوف الرفع السيئة من قاعدة بياناتك بشكل نهائي.

إذا لم يكن لديك أي رفع، فلا تحتفظ به هناك.

نعم، أنا أتفق معك، لكنني أخشى من تنفيذ أمر تدمير جماعي (nuke) يدويًا على قاعدة البيانات. هل لديك أي اقتراحات للقيام بذلك بالطريقة “الصحيحة”؟ أم يجب أن أقوم به فعليًا “يدويًا”؟

أيضًا، أشعر أن هذا التغيير في سلوك Discourse مقلق بعض الشيء. فهذا يعني، بقدر ما أستطيع استنتاجه، أنه إذا وُجد رابط صورة تالف في أي مكان، فإن التطبيق ستنهار.

لم يكن الأمر كذلك من قبل. وأقترح جعل النظام أكثر قوة في مثل هذه المواقف.

شبيه جداً بما لدينا:

تمت “إصلاح” المشكلة بإعادة تشغيل إعداد المعالج!

نعم، يبدو أن هذه هي المشكلة نفسها. @sukria، إذا قمت بتحديث النسخة إلى أحدث إصدار تم اختباره بنجاح، فقد أضفت إصلاحًا يجعل الأمور أكثر متانة في حالة فشل عمليات التحميل (على الرغم من أنه لا يزال عليك محاولة تنظيف مراجع عمليات التحميل الفاشلة).

أنا مهتم أيضًا بطريقة سهلة لتنظيف تلك الروابط المعطلة أيضًا :wink:

شكرًا لك @david، أؤكد أن إعادة البناء الجديدة ضد tests-passed عملت دون أي مشاكل. شكرًا!
هل لديك أي اقتراح لطريقة صحيحة أو سهلة للتخلص من تلك الروابط التالفة في المواضيع؟