لديّ أمران أريد معالجتهما بعد ذلك: الأول هو أن الحد مفيد، لكنه يقتصر فقط على مساحة البحث؛ بعد ذلك أريد أن أتمكن من تحديد الحد الأقصى لعدد المنشورات المراد تعديلها. لذا سأحتاج إلى إضافة حد أقصى لعدد المنشورات المراد تعديلها، بالإضافة إلى حد للاستعلام.
أيضًا، عند تحديد max، من المنطقي أن نكون واضحين ومفصلين بشأن ما يتم معالجته لأغراض التصحيح، لذا أود جعل المخرجات مفصلة إذا لم يكن max يساوي nil — وهذا سيسمح للمستخدمين بالتحقق من العملية قبل المتابعة، نظرًا لأن هذا هو الاستخدام الرئيسي لهذا العمل.
أعتقد أن ما سأفعله هو تحديد max كمعلمة أولى، وحد اختياري كمعلمة ثانية، لأن max هو الأهم حقًا؛ أما الحد فهو مجرد وسيلة لجعل “نقرة واحدة فقط” أقل تكلفة.
الأمر الثاني هو غير الرفع: الرفع. قبل أكثر من عام، حاولت رفع فيديو إلى موقع Discourse الذي كنت أنضم إليه، بينما كنت أتخبط في محاولة فهم كيفية كتابة عملية الهجرة من Google+ إلى Discourse، ولاحظت أن ما كُتب كان https://#{SiteSettings.absolute_base_url}/original/3X/b/a/ba9e06ebc2f4397f26793bb5cd4e169308dd371d.mp4
اليوم، عندما أرفع فيديو، أحصل على شيء مثل  بدلاً من ذلك.
على الأقل في أحدث اختبار لي، قام migrate_from_s3 بتشويه هذه الروابط تمامًا، مما جعلها لم تعد روابط على الإطلاق، لذا يجب إصلاح ذلك بالتأكيد. بعد ذلك، أعتقد أن هذه المهمة من غير المرجح عمليًا أن تواجه ، لذا كخطوة أولى، أود فقط إضافة تنسيق الرابط الماركداون حول بروتوكول upload السحري، بدلاً من جعل التعبير النمطي يتعامل مع الحالتين ويصبح أكثر صعوبة في القراءة نتيجة لذلك. لكن قد أغير رأيي في ذلك.
يبدو أن وسم video أو audio يُضاف بواسطة جافا سكريبت عبر مطابقة تعبير نمطي، لذا سأحتاج إلى نسخ التعبيرات النمطية من app/assets/javascripts/discourse/app/lib/uploads.js إلى المهمة لتحديدها بشكل صحيح. سأشمل مصدر التعبيرات النمطية حتى يعرف الشخص التالي الذي يعثر عليها مكان تحديثها. ![]()
…
في هذه الليلة، خصصت بعض الوقت للعمل على هذا، ولدي مسودة لطلب سحب (PR) قيد التنفيذ. إنها ليست مكتملة بعد؛ أعرف أن هناك أخطاءً لا تزال موجودة فيها. لا أعتقد أنني غيّرت أي سلوك لروابط بروتوكول upload: الوهمي (طبيعي للصور) حتى الآن، رغم أنني أضفت فحصًا منطقيًا.
مع التغييرات في هذا الطلب السحب، نجحت في هجرة كل من الرفع العادي باستخدام بروتوكول upload: الوهمي والفيديوهات التي يتم الرجوع إليها حاليًا صراحةً عبر S3 (حسنًا، في حالتي، مساحات Digital Ocean). أنا أستخدم هذا لتعديل منشور واحد فقط في كل مرة باستخدام هذا الأمر:
bin/rake uploads:batch_migrate_from_s3[1,1000]
لاحظ أن هذا لن يتجاوز أول 1000 منشور يتم إرجاعها بشكل عشوائي نوعًا ما من استعلام قاعدة البيانات؛ الحد المنخفض هو فقط من أجل السرعة عند إجراء الاستعلام أثناء هجرة منشور واحد فقط في كل مرة، ومراجعة ذلك المنشور للتأكد من السلوك الصحيح ثم البدء من جديد للعثور على منشور آخر. يعمل هذا الأمر بهذه الطريقة فقط مع طلب السحب الذي أعمل عليه حاليًا!
…
أنا أواصل إضافة مخرجات تشخيصية أثناء عملي على هذا، وأبدأ في التفكير في أن هذا مهم لأكثر من مجرد التطوير. أرى العديد من حالات فشل التحميل العابرة من مساحات Digital Ocean حيث يتم هجرة بعض التحميلات في منشور ما وليس جميعها، وهو ما في الأصل سيُطبع فقط . ويستمر ثم يقول Done، لكن في الواقع لن تكون المهمة مكتملة. اضطررت إلى إجراء ما بين خمس أو ست عمليات تكرار على منشور واحد قبل هجرة جميع الملفات. (لم أكن أحسب لأنني اعتقدت في البداية أنني أعالج خطأً محليًا.) أتوقع أن أحتاج إلى تشغيل هذه الهجرة بشكل متكرر مع نفس الحد حتى تصبح التشخيصات نظيفة. لذلك، سأجعل طباعة التقدم المفصل تظهر فقط إذا تم تعيين max، لكن سأطبع رسائل تحذير مفيدة في كلتا الحالتين.
حاليًا، أستخدم الحيلة التالية لمشكلة فشل التحميل المتقطع من مساحات Discourse، والتي أدت عمليًا إلى تحسين معدل نجاحي بشكل هائل (ثلاث محاولات كانت كافية تمامًا عبر مئات المنشورات المهاجرة حتى الآن).
https://github.com/johnsonm/discourse/commit/7dfac12a2ea6ec04ba4e0616b4e0dbd1d806cff7
أيضًا، اكتشفت أننا بطريقة ما انتهى بنا الأمر إلى الحصول على فيديوهات أكبر من الحد الذي حددته عند الاستيراد من Google+ — وقد اضطررت إلى زيادة مؤقتة لكل من SiteSettings.max_image_size_kb و SiteSettings.max_attachment_size_kb أثناء عمليات الهجرة الفردية لبعض الفيديوهات الكبيرة الحجم التي لا يتضح لي كيف انتهى بها الأمر على الموقع، لكنني لا أريد كسرها الآن… لا أعرف ما إذا كان الخطأ الذي سمح برفع ملفات كبيرة الحجم كان في سكريبت الاستيراد الخاص بي، أو في Discourse، أو مجرد ذاكرتي حول التغييرات التي أجريتها على الإعدادات بمرور الوقت. ![]()
نظرًا لأن الكثير مما أهاجره كان استيرادًا من G+، فإن بعض منشوراتي فشلت في عمليات التحقق الحالية. حصلت على بعض رسائل Unhandled failure: Validation failed: Sorry, new users can only put one image in a post ولم أفهم في البداية لماذا لم تتكرر. اتضح أن الملفات تم نقلها بنجاح إلى المحلي، واستخدمت جميعها بروتوكول upload: الوهمي، لذا لم يتغير النص الخام. ومع ذلك، فشل post.save! بنفس الخطأ في عمليات التحقق، مما منع post.rebake! من التنفيذ، لذا لدي بعض المنشورات من أصل 30 ألفًا تحتوي على صور تحتاج إلى إعادة معالجة؛ للأسف، ليس لدي أي سجل عن أي منشورات هي تلك. لقد تحولت الآن إلى استخدام post.save!(validate: false) كإصلاح آخر، لذا يجب ألا تتكرر هذه المشكلة تحديدًا. أنا سعيد جدًا لأنني جعلت الهجرة تتوقف عند الأخطاء غير المعالجة، وإلا لكان ذلك قد تسبب في أضرار أكبر بكثير من مجرد بعض المنشورات.
…
لإبقاء موقعي قابلاً للاستخدام، بما في ذلك تسليم الإشعارات، أثناء تشغيل الهجرة، لا أريد إغراق طوابير Sidekiq. أعرف أن تسمية الأشياء هي واحدة من أصعب مشكلتين في علوم الحاسوب، إلى جانب إبطال التخزين المؤقت وأخطاء العد الزائد أو الناقص، لكنني أقترح DISCOURSE_MIGRATION_MAX_ENQUEUED كمتغير بيئة يحدد العدد الإجمالي لمقاعد الطابور (وليس مقاعد الوظائف) المسموح بملئها عند المتابعة لترحيل عنصر آخر بعد rebake أثناء الهجرة، لتجنب إغراق الطوابير، بحيث يستمر الموقع في العمل. لدي تصحيح يضيف هذا، مع افتراض القيمة صفر، لجميع عمليات إعادة المعالجة لكل منشور في lib/tasks/uploads.rake. أنا أستخدم هذا في هجرتي الإنتاجية.