واجهت مشكلة متقطعة أثناء تحرير منشور موجود في مثيلي الخاص بـ Discourse المستضاف ذاتيًا في 21 أكتوبر 2026. أصبح المُحرر (Composer) عالقًا في حالة الحفظ، ولم أتمكن من العودة إلى المحرر لاستعادة بعض النص المُملى صوتيًا.
منذ ذلك الحين، فحصت سجلات الوصول الخاصة بـ Caddy وnginx وسجل مراجعات المنشورات في Discourse.
البيئة
-
العميل: iPhone 16 Pro، تطبيق Safari PWA على شاشة الرئيسية
-
iOS: 27.0.1
-
Discourse:
2026.10.0-latest +406 commits، كما ظهر في لوحة التحكم الإدارية لاحقًا في نفس اليوم (يتوفر 162 تغييرًا أحدث) -
الاستضافة: استضافة ذاتية، أرشيف دراسي خاص
-
الوكيل العكسي: Caddy v2.11.4، يوفر HTTP/3 عبر QUIC
-
الخلفية: nginx لـ Discourse خلف Caddy باستخدام Unix socket
-
الشبكة: شبكة Wi-Fi الجامعية في البداية، ثم اتصالات EE الخلوية
ما حدث
كنت أحرر منشورًا يحتوي على صورة لشريحة محاضرة في الفيزياء.
ملّلت ملاحظات رياضية إضافية، بما في ذلك الكسور، أسفل الصورة، ثم ضغطت بسرعة على زر حفظ التعديل.
ظل شريط الحفظ الأفقي الأزرق ظاهرًا في أسفل الشاشة ولم يكتمل.
حاولت لمس شريط الحفظ، لكن هذا لم يعيد فتح المُحرر. ونتيجة لذلك، لم أتمكن من تحديد أو نسخ النص غير المحفوظ في مكان آخر.
انتظرت لفترة أطول مما أفعله عادةً.
فقط بعد أن علق عملية الحفظ بالفعل، عطّلت Wi-Fi يدويًا، آملًا أن يسمح التبديل إلى الشبكة الخلوية بإكمال الطلب.
لم تستعد الواجهة عملها فورًا. كما واجهت مشاكل في التخزين المؤقت (buffering) عند محاولة التنقل باستخدام شعار الموقع.
عندما تمكنت من تحرير المنشور مرة أخرى، كانت الكسور المُملاة مفقودة.
التحقيق من جانب الخادم
كان الوقت المرتبط بالحادث حوالي 12:20 بتوقيت BST في 21 أكتوبر 2026.
تظهر سجلات Caddy لدي:
| الوقت (BST) | الطلب | النتيجة |
|---|---|---|
| 12:19:39 | POST /drafts.json |
200 |
| 12:19:40 | POST /uploads.json |
200 |
| 12:19:44 | POST /drafts.json |
200 |
| 12:20:08 | PUT /posts/70695 |
حالة Caddy 0 |
| 12:20:55 | PUT /posts/70695 |
200 |
استخدم طلب PUT غير الناجح بروتوكول HTTP/3. سجّل Caddy مدة زمنية تقارب 110 مللي ثانية، بينما سجّل nginx استجابة HTTP 400 دون تنفيذ أي وحدة تحكم لتحديث منشورات Discourse.
تلقى العديد من الطلبات الأخرى المنبعثة من الاتصال الخلوي أيضًا حالة Caddy 0 في نفس الوقت تقريبًا.
لم يُعاد تشغيل Caddy نفسه. يقر Docker بصفر عمليات إعادة تشغيل منذ 15 أكتوبر، ولا تحتوي السجلات التشغيلية على أي حدث إعادة تحميل أو إيقاف تشغيل مطابق.
استعادة المسودات
كانت هناك طلبات حفظ مسودات ناجحة مباشرة قبل الحادث.
ومع ذلك، أتذكر المحتوى السابق على أنه صورة الشريحة دون النص الإضافي المُملى. أدخلت الكسور بعد ذلك وضغطت على حفظ التعديل بعد فترة وجيزة.
لذلك، لا أستطيع إثبات أن الإملاء المفقود كان مدرجًا في أي من الحفظ التلقائي الناجح.
عندما فحصت مراجعات المنشور لاحقًا، احتوت المراجعة الناجحة عند 12:20:55 على الصورة ولكن ليس الكسور المُملاة.
كما قمت بفحص سجلات المسودات الحالية، لكن لا المفتاح القديم ولا المفتاح الجديد لمسودة الموضوع احتويا على مسودة متبقية وقت الفحص.
السلوك المتوقع
إذا علق طلب التعديل أو انقطع، فأنا أتوقع أن يحافظ المُحرر على محتوياته غير المحفوظة ويوفر طريقة لإعادة المحاولة أو الإلغاء أو العودة إلى التحرير.
على وجه الخصوص، يجب ألا تجعل الواجهة النص غير المحفوظ غير قابل للوصول بشكل دائم أثناء عرض حالة “الحفظ”.
السلوك الفعلي
ظل المُحرر غير قابل للوصول، ولم يعِد لمس شريط الحفظ فتحه، ولم يعد النص المُملى متاحًا عند استئناف التحرير.
الأسئلة
-
هل يُتوقع أن يبقى المُحرر غير قابل للوصول بشكل دائم أثناء وجود طلب تعديل قيد الانتظار؟
-
هل يوجد مهلة زمنية (timeout) أو آلية استرداد مخصصة لاستعادة التحرير عندما ينقطع طلب الشبكة؟
-
هل يجب أن تحفظ عملية حفظ التعديل المقطوعة النص في الذاكرة أو محتويات المسودة حتى لو لم يصل الطلب أبدًا إلى وحدة تحكم تحديث المنشورات في Rails؟
-
هل سيكون أي تسجيل أو أداة قياس خاصة بالعميل مفيدة إذا تكرر هذا الأمر على iOS؟
أقدّر أن تغيير الشبكة قد يفسر إلغاء الطلبات النهائية. ومع ذلك، أصبحت واجهة الحفظ عالقة قبل أن أقوم بتغيير الشبكات يدويًا.
لم أحدد ما إذا كان التأخير الأولي ينبع من جافاسكريبت الخاص بـ Discourse، أو شبكات iOS/WebKit، أو اتصال الجامعة.
مناقشات ذات صلة
لدي نقاش قائم حول MPTCP / استمرارية الاتصال في iOS، حيث وصفت هذا الحادث نفسه من منظور النقل.
كما قمت سابقًا بالإبلاغ عن المشاهدات المعدلة التي تبقى قديمة أحيانًا في DiscourseHub على iOS. في تلك المشكلة المنفصلة، كانت التعديلات قد وصلت إلى الخادم بنجاح، لكن المنشور المعروض بالفعل لم يتحدث حتى يتم تحديث الصفحة. لاحظ مستخدم آخر ذلك السلوك أيضًا.
لا أعرف ما إذا كانت المشكلتان تشتركان في سبب واحد. الحادث الحالي مختلف لأن طلب تعديل المنشور الأولي لم تتم معالجته بنجاح.
كما وجدت تقريرين سابقين يتضمنان مُحررًا عالقًا في حالة الحفظ:
كان لكل منهما أسباب محددة مختلفة، وأنا لا أفترض أنها تفسر هذا الحادث.
أرفقت ملف ZIP discourse_ios_save_evidence_2026-10-21_domain_redacted.zip (6.3 كيلوبايت) يحتوي على مقتطفات تشخيصية مختارة ومحذوفة من Caddy/nginx، ومعلومات المراجعات، والجدول الزمني الوارد أعلاه.
سأكون ممتنًا لأي نصائح حول كيفية استرداد المُحرر من الطلب المتوقف، خاصة عندما لا يمكن نسخ التغييرات غير المحفوظة قبل انقطاع الشبكة.