@Falco مرحباً، واجهتُ عدة مشاكل قابلة للتكرار أثناء اختبار النسخة المحدّثة من resenha. أشارك معكم النتائج بالإضافة إلى التصحيحات التي أطبّقها محلياً، في حال كانت مفيدة للتطوير الأصلي.
1. واجهة المسؤول تتجاهل بصمت خاصية room_type مما يمنع الغرف من البقاء في وضع “المراحل” (stage)
يُستبعد :room_type من قائمة السماح في app/controllers/resenha/admin_rooms_controller.rb:65 (room_params)، كما لا يقوم admin_room_serializer.rb بتسلسله (serialize).
يتم تجاهل كل تعيين للمراحل يتم عبر واجهة المسؤول، وتُنشأ الغرف كـ “مفتوحة” وتعود إلى الوضع المفتوح عند أي تعديل لاحق من قبل المسؤول. تم التأكيد على ذلك عبر سجلات الإنتاج؛ متحكم واجهة المستخدم يسمح بذلك، لكن المسار الخاص بالمسؤول فقط هو الذي فقد هذه الخاصية.
# admin_rooms_controller.rb — أضف :room_type إلى قائمة السماح، ثم:
if permitted.key?(:room_type)
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value
end
# admin_room_serializer.rb — سّلسل room_type بحيث تتهيأ النماذج بشكل صحيح
2. القيم غير الصالحة لـ room_type تعود بصمت إلى الوضع المفتوح
app/controllers/resenha/rooms_controller.rb:575 — ROOM_TYPES[...] || ROOM_TYPE_OPEN.
أي قيمة غير صحيحة أو قديمة لـ room_type في تعديل غرفة صحيح بخلاف ذلك، يقوم بصمت بتحويل غرفة المراحل إلى وضع مفتوح. إرجاع خطأ 400 يجعل المتصل الذي يتصرف بشكل خاطئ مرئياً بدلاً من إتلاف بيانات الغرفة.
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value
3. نبضات الحياة (Heartbeat) تعيد إحياء مستخدم غادر للتو (حضور شبحي)
rooms_controller.rb:234 (heartbeat) يعيد إضافة الحضور بشكل غير مشروط، لذا فإن نبضة حياة قيد المعالجة عندما تتم معالجة عملية المغادرة (:220) لاحقاً، تعيد إنشاء المستخدم المغادر.
يبقى هذا “الشبح” حتى يتم تنظيفه بناءً على انتهاء وقت البقاء (TTL)، وهو ما لا يُبثّ — فتظهر للعملاء وكأنه “في الغرفة” لمدة تصل إلى دقيقة.
تم تكرار المشكلة على الجهاز؛ ولأمر الطرد (kick) نفس التعرض للمشكلة.
# ParticipantTracker: حجر نصب مدته 15 ثانية
def mark_left(room_id, user_id) = redis.setex(left_key(room_id, user_id), 15, "1")
def recently_left?(room_id, user_id) = redis.exists?(left_key(room_id, user_id))
# leave/kick → mark_left; join/livekit_token → clear_left; heartbeat:
return head :no_content if Resenha::ParticipantTracker.recently_left?(@room.id, current_user.id)
4. إشارة webhook قديمة لـ participant_left تطرد جلسة جديدة
livekit_webhooks_controller.rb:37/57 — يتم مطابقة المغادرات بناءً على هوية المستخدم فقط.
عند انقطاع سريع وإعادة انضمام، تصل إشارة participant_left الخاصة بالجلسة السابقة متأخرة وتُنتهي صلاحية حضور الجلسة الجديدة (يتم “طرد” المستخدم بعد ~3 ثوانٍ من إعادة الانضمام، ويعود بعد ~15 ثانية).
تم تكرار المشكلة على الجهاز؛ ولا يمكن لمعيار gone_at التمييز بين الجلسات عندما يسبق إعادة الانضمام انقطاع الجلسة القديمة.
# participant_joined → تسجيل SID المباشر
Resenha::ParticipantTracker.set_livekit_sid(room.id, user_id, event.dig("participant", "sid"))
# expire_participant → تخطي مغادرة الجلسة السابقة
known = Resenha::ParticipantTracker.livekit_sid(room.id, user_id)
return if sid.present? && known.present? && sid != known
5. خطأ 404 لـ DeleteRoom بعد مغادرة آخر مستخدم يفيض السجلات
lib/resenha/livekit/room_service_client.rb:84 يحذر عند أي استجابة غير 200.
يقوم SFU بإغلاق الغرفة تلقائياً في اللحظة التي تصبح فيها فارغة، لذا فإن طلب DeleteRoom الخاص بالمغادرة الأخيرة يتسابق معه بشكل روتيني — و"الغرفة المطلوبة غير موجودة" هي الحالة النهائية المطلوبة، وليست عطلاً.
يظهر هذا في Logster عند كل مغادرة للمستخدام الأخير.
elsif method == "DeleteRoom" && response.status == 404
Rails.logger.debug("[resenha-livekit] DeleteRoom no-op for room #{room.id}: already gone")
true
يمكنني إرسال طلب سحب (pull request) إذا رغبت في ذلك.
كما قلتُ سابقاً، لا أعرف اتجاهكم بالكامل، لكنكم يمكنكم الاطلاع على مساهماتي حيث قمتُ بنشر موضوع هنا → Discourse Desktop Mac App - #10 by nicolsdennis