إضافة حد أقصى للعمق المتداخل للتفاصيل القابلة للطي

أودّ اقتراح إضافة حدّ أقصى للعمق المتداخل (nesting depth) لميزة [details] المدمجة، أو تقديم إعداد موقع يسمح للمشرفين بضبط هذا الحد.

المشكلة

مؤخراً، أنشأ مستخدم على منتدي Discourse منشوراً يحتوي على 24 مستوى من الأقسام [details] المتداخلة.

أدى هذا إلى عدة مشاكل:

  1. أداء المتصفح: أبلغ المستخدمون عن أن توسيع عدة مستويات تسبّب في بطء شديد أو عدم استجابة متصفح Firefox.
  2. انتهاء مهلة نقاط نهاية Markdown: أصبح الوصول إلى نقطة النهاية .md للموضوع بطيئاً جداً. لاحظنا طلبات تستغرق 19.8 ثانية و31.1 ثانية.
  3. أخطاء الخادم: كانت نقطة نهاية Markdown تعيد أحياناً صفحة خطأ “Oops”. كما أظهرت سجلات Discourse تحذيرات انتهاء مهلة عامل Pitchfork أثناء تحويل Markdown.
  4. استنفاد الموارد المحتمل: نظراً لأن محركات البحث وروبوتات الزحف (AI crawlers) تطلب نقاط النهاية .md بشكل متكرر، فقد يتسبب منشور متداخل بعمق في تشغيل عمليات معالجة مكلفة بشكل متكرر واستهلاك موارد الخادم.

بعد إزالة المنشور المعيب، عادت نقطة نهاية Markdown إلى إرجاع HTTP 200 واستجابت في حوالي 1.7 ثانية.

كان الموضوع المتأثر هو:

https://meta.appinn.net/t/topic/87672

(تمت إزالة الرد المعيب بالفعل.)

التحسين المقترح

أعتقد أنه سيكون مفيداً إما:

  • تقييد تداخل [details] بعمق معقول، مثل مستويين أو ثلاثة مستويات.
  • إضافة إعداد موقع، مثل details_max_nesting_depth، يسمح للمشرفين بضبط الحد الأقصى للعمق المتداخل.

من أجل التوافق الخلفي، يمكن أن يكون الإعداد الافتراضي غير محدود، مع السماح للمشرفين بفرض حد عند الحاجة.

إذا تجاوز المستخدمون الحد المهيأ، يمكن لـ Discourse رفض المنشور مع رسالة تحقق واضحة.

حل مؤقت: إضافة (Plugin)

أنشأت إضافة صغيرة تحدّ من تداخل [details] إلى حد أقصى مستويين:

GitHub - scavin/discourse-details-depth-limit · GitHub

تتحقق الإضافة من المنشورات على جانب الخادم وترفض المنشورات التي تحتوي على أكثر من مستويين من الأقسام القابلة للطي المتداخلة.

اختبرتُها بنجاح في بيئة تطوير Discourse المحلية لدي.

بالنسبة للمشرفين الذين يواجهون مشاكل مشابهة، قد تكون هذه الإضافة حلاً مؤقتاً حتى يتوفر حل رسمي.

أعتقد أن وجود حد قابل للتخصيص في إضافة Details المدمجة سيكون إجراءً وقائياً مفيداً ضد التداخل العرضي أو المفرط.

3 إعجابات

مرحباً @scavin، شكراً لك على الإبلاغ عن هذه المشكلة وتوفير تفاصيل إعادة إنتاجها.

لقد كنت أبحث في بطء نقطة النهاية الخاصة بـ Markdown التي وصفتها، وحديت مشكلة في MarkdownEndpoint::CookedProcessor#replace_details: حيث كانت عناصر <details> المتداخلة تُحوَّل بشكل متكرر، مما أدى إلى معالجة أُسّية (exponential processing).

لقد فتحت طلب سحب (PR) مسودة (draft) على المنبع (upstream) يحتوي على الإصلاح:

https://github.com/discourse/discourse/pull/44461

عند مستوى تدخّل ثامن، قلّل الإصلاح عمليات التحويل التكرارية من 255 إلى 8، مع تحقيق تسريع يقارب 31 ضعفًا في اختباري المحلي للأداء. وقد اجتاز طلب السحب فحوصات GitHub CI الأولية.

أعمل أيضًا على إعداد الموقع المقترح من قِبلك details_max_nesting_depth داخل إضافة Details المدمجة، باستخدام 0 لـ عدم تحديد حد للتدخّل للحفاظ على السلوك الحالي. تم كتابة التنفيذ الأولي، لكن اختبارات التكامل لا تزال قيد الإنجاز.

يعالج إصلاح الأداء مشكلة تحويل Markdown على جانب الخادم؛ بينما سيوفر الحد القابل للتخصيص حماية إضافية، خاصةً لأداء جانب المتصفح.

أرحب بالملاحظات حول الإعداد المقترح، وما إذا كان من الأفضل تضمينه في نفس طلب السحب أو إرساله بشكل منفصل.

إعجابَين (2)

شكرًا لك على البحث السريع وإصلاح المشكلة! أعتقد أنه من الأفضل فصلهما إلى طلبَي دمج (PRs) منفصلين، بحيث يمكن مراجعة دمج إصلاح الأداء بشكل مستقل دون انتظار الإعداد الجديد. كما أؤيد حد العمق القابل للضبط، مع جعل القيمة الافتراضية صفرًا لضمان التوافق مع الإصدارات السابقة.

إعجاب واحد (1)

شكرًا لك @scavin. أستطيع أن أرى الفائدة من فصلهما، على الرغم من أن كلا التعديلين يعالجان نفس المشكلة الأساسية التي أبلغتَ عنها، وقد تم تنفيذهما واختبارهما بالفعل عبر CI. لقد فعّلتُ تحرير المُشرفين على جميع طلبات المساهمة (PRs) الخاصة بي، لذا يسعدني أن أتبع تفضيل فريق Discourse، سواء كان ذلك بمراجعة كلا الالتزامين (commits) معًا أو بفصلهما.

إعجابَين (2)

شكرًا لـ @scavin على الإبلاغ، ولـ @Ethsim2 على طلب الإرسال :+1: قمت بتحديث طلب الإرسال ليكون أكثر انضباطًا، بالإضافة إلى تحديد أقصى مستوى للتسلسل الهرمي عند 10. لست متأكدًا من أننا سنحتاج إلى دعم أكثر من ذلك على أي حال.

3 إعجابات