التعديلات لا تُخزَّن في جدول user_actions

اعتقدتُ أن كل مرة يقوم فيها مستخدم بتعديل منشور لشخص آخر، سيتم تسجيل هذا الإجراء في جدول user_actions، لكنني أدركت للتو أن هذا يحدث بشكل متقطع (فقط لبعض المستخدمين في بعض الأوقات).

هل هذا هو السلوك المقصود أم أن هناك شرطًا آخر لم أأخذه في الاعتبار؟

من الصعب تقديم خطوات متسلسلة لإعادة إنتاج هذه المشكلة، لكن هذا هو كيفية اكتشافي لها:

  1. ابحث عن منشور يحتوي على إشعار تعديلات:
  2. استعلم عن جدول user_actions باستخدام acting_user_id المعطى (المحرر)، وuser_id المعطى (المُعدَّل)، وtopic_id المعطى. في حالتي:
select * from user_actions ua 
where ua.acting_user_id = 229 
and ua.user_id = 259 
and ua.target_topic_id = 1907;

هذا ما حصلت عليه:

  • نوع الإجراء 2 يعني أن المستخدم المُعدَّل تلقى إعجابًا (LIKE) من المحرر.
  • نوع الإجراء 6 يعني أن المحرر رد على المستخدم المُعدَّل.
  id   | action_type | user_id | target_topic_id | target_post_id | target_user_id | acting_user_id |         created_at         |         updated_at
-------+-------------+---------+-----------------+----------------+----------------+----------------+----------------------------+----------------------------
 78476 |           2 |     259 |            1907 |          17893 |                |            229 | 2020-03-20 03:39:12.255619 | 2020-03-20 03:39:12.395574
 78478 |           6 |     259 |            1907 |          17900 |                |            229 | 2020-03-20 03:44:04.847102 | 2020-03-20 03:44:04.847102

يمكنني تأكيد كلا هذين الإجراءين في واجهة المستخدم، لكنني أتوقع أيضًا العثور على action_type 11 يشير إلى التعديل (EDIT).

بصرف النظر عن رؤية التعديل في واجهة المستخدم، يمكنني أيضًا تأكيد وجوده في جدول post_revisions عن طريق الاستعلام باستخدام target_post_id:

select id, user_id, post_id, number, created_at, updated_at from post_revisions pr where post_id = 17893;

  id  | user_id | post_id | number |         created_at         |         updated_at         |
------+---------+---------+--------+----------------------------+----------------------------+--------
 8927 |     229 |   17893 |      2 | 2020-03-20 03:40:06.644576 | 2020-03-20 03:43:32.769535 |

إذن، لماذا لا يظهر هذا الإجراء في user_actions؟

لا يُقصد تخزين التعديلات هناك، بل يتم تخزينها في post_revisions.

حسناً، ليس التعديل. أقصد حدث user_action EDIT:

المسألة هي أنه يُفعّل في 90% من الحالات. لا أفهم لماذا لا يعمل في الـ 10% المتبقية.

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

الافتراضات الرئيسية

إذا قام المستخدم أ بتعديل ما كتبه المستخدم ب، فإن عدة أشياء تحدث:

  • يتم إضافة صف جديد إلى جدول post_revisions.
  • يتم إضافة صف جديد إلى جدول user_actions مع action_type = 11.
  • من خلال الانتقال إلى /u/userB/notifications/edits، سيتمكن المستخدم ب من رؤية أن المستخدم أ قام بتعديل جديد (يعتمد هذا على user_actions).
  • من خلال النقر على أيقونة القلم الرصاص في منشوره، سيتمكن المستخدم ب من رؤية التعديل الفعلي الذي قام به المستخدم أ (يعتمد هذا على post_revisions).

الاختبار

إذا كانت الافتراضات أعلاه صحيحة، فيجب أن يعرض هذا الاستعلام جميع الصفوف في جدول post_revisions للمنشورات التي أنشأها المستخدم ب (في هذه الحالة، المعرف 259) والتي تم تعديلها من قبل أي مستخدم (بخلاف نفسه أو مستخدم النظام)، بالإضافة إلى الصفوف المقابلة في user_actions لـ action_type = 11.

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 259 -- اختر معرف مستخدم
)
select
  up.user_id as my_user_id,
  ua.user_id as target_user_id,
  pr.post_id,
  ua.target_post_id,
  pr.user_id as editor_user_id,
  ua.acting_user_id,
  ua.action_type,
  pr.created_at as edit_created_at,
  ua.created_at as action_created_at
from
  post_revisions pr
  inner join my_user_posts up on up.id = pr.post_id
  and up.user_id != pr.user_id -- لا توجد تعديلات ذاتية
  and pr.user_id != -1 -- لا توجد تعديلات نظام
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- إجراءات التعديل فقط
order by
  pr.post_id,
  pr.created_at;

المخرجات المتوقعة

كل صف يحتوي على بيانات post_revisions بالإضافة إلى بيانات user_actions.

المخرجات الفعلية

بعض صفوف post_revisions لا تحتوي على بيانات user_actions مطابقة. لذلك، يمكن للمستخدم رؤية التعديلات من خلال النقر على القلم الرصاص في كل منشور، ولكن لم يتم إشعاره بتلقي عدة تعديلات.

الأشياء التي جربتها

  • إضافة تعديل إضافي إلى منشور قديم لا يحتوي على بيانات user_action. النتيجة: لم تظهر بيانات user_action أيضًا.
  • إنشاء مستخدم وهمي، ونسخ محتوى ما قبل التعديل لمنشور لا يحتوي على بيانات user_action، وإنشاء منشور به، وتطبيق نفس التعديل الذي تم تنفيذه مع مستخدم مختلف. النتيجة: ظهرت بيانات user_action بشكل صحيح.
  • تكرار الإجراءات المذكورة أعلاه عندما يكون المستخدم نشطًا أو غير متصل. النتيجة: لا تغيير.
  • تكرار الإجراءات المذكورة أعلاه مع تغيير فترة سماح التعديل. النتيجة: لا تغيير.

الاستنتاجات

  • لا يبدو أن المشكلة:

    • خاصة بالمستخدم. فهي تحدث تقريبًا لكل مستخدم.
    • خاصة بالاتصال. حقيقة أن المستخدم نشط أو غير متصل لا تغير المخرجات.
    • خاصة بالوقت. لم يكن لتغيير فترة سماح التعديل أي تأثير.
  • يبدو أن المشكلة:

    • خاصة بالإجراء. لم أرَ أي مشاكل في إشعار أي من الإجراءات الأخرى (LIKE, WAS_LIKED, RESPONSE, REPLY, MENTION أو QUOTE). المشكلة الوحيدة هي مع إجراءات التعديل.

    • خاصة بالمنشور. لا تحدث لكل منشور، بل لمنشورات محددة (يبدو أنها عشوائية)

  • احتمال واحد هو أن شيئًا ما يحدث أثناء إنشاء منشورات معينة لمنع حفظ إجراءات user_actions الخاصة بالتعديل، لكنني لا أعرف ما يمكن أن يكون هذا الشيء.

  • من الممكن أيضًا أن يحدث هذا عن قصد وأن هناك ظروفًا محددة لا يتم فيها إشعار المستخدمين بالتعديلات، لكنني لم أرَ ذلك موثقًا في أي مكان.

الخطوات التالية

  • إذا كنت تعرف سببًا لعدم تشغيل إشعارات التعديل في كل مرة يتم فيها إجراء تعديل، فيرجى إخباري.
  • إذا كان لديك مثيل Discourse خاص بك، هل يمكنك تشغيل استعلام SQL المذكور أعلاه على بعض معرفات المستخدمين الخاصة بك لمعرفة ما إذا كنت ترى أيضًا بيانات user_actions مفقودة والإبلاغ عن النتيجة؟

أريد فقط التأكد بنسبة 100% من أنك واضح بشأن فترات سماح التحرير، والتي ستظل سارية حتى لو كان مستخدم آخر يقوم بتحرير المنشور.

(نعم، إذا قام المستخدم أ بتحرير منشور المستخدم ب، فهناك دائمًا مراجعة تحرير قسرية، لكن هذا لا يعني أنه إذا قام المستخدم أ بتحرير منشور المستخدم ب 6 مرات خلال 60 ثانية، فسيتم إنشاء 6 مراجعات و6 إشعارات. ستكون هناك مراجعة واحدة وإشعار واحد فقط، كما يمكنك رؤية ذلك في لقطة الشاشة أعلاه.)

هل كل هذه التعديلات على مسافة تزيد عن 5 دقائق عن بعضها البعض؟

شكرًا لك على التعليق، جيف. يمكنني تأكيد أن هذه التعديلات تفصل بينها أكثر من 5 دقائق. ولكن حتى لو لم يكن الأمر كذلك، طالما تم إنشاء post_revision واحدة فقط، ألا يجب أن يكون هناك دائمًا EDIT user_action مصاحب لها؟

كملاحظة جانبية، جربت أيضًا تغيير فترة السماح في التعديل إلى 0، وعندما أفعل ذلك، يتم إنشاء post_revisions متطابقة لكل تغيير. لا أعرف ما إذا كان هذا مقصودًا أم أنه خطأ غير مرتبط بهذا.

فقط للتأكد من ذلك، من الجيد التأكيد.

هل يمكن لأحد تنفيذ الاستعلام أعلاه على موقع Discourse الخاص به لمعرفة ما إذا كان يحصل أيضًا على post_revisions دون وجود user_actions من النوع 11؟

عند البحث في كودنا، أعتقد أنك تحصل على نوع user_action رقم 11 فقط إذا قمت بتحرير منشور لشخص آخر أو قمت بإثارة إشعار يتعلق بالتحرير بطريقة أخرى.

شكرًا لك، سام. هذا ما كنت أتوقعه، لكنه ليس ما وجدته (على موقعي على الأقل). كما يمكنك أن ترى من نتائج استعلامي، في بعض الحالات، يقوم المستخدم أ بتحرير منشور للمستخدم ب (مما يضيف سطرًا في post_revisions)، لكن لا يوجد سطر مقابِل في user_actions (مع action_type 11). هذا ما لا أفهمه.

هل لديك تكرار للمشكلة؟ هل هي حادثة لمرة واحدة؟

حدث ذلك بشكل مستمر ومتقطع منذ أن بدأت موقعي. لم أتمكن من رؤية النمط كما ذكرت أعلاه.

إذا كان هناك طريقة يمكنني من خلالها تزويدك بتصدير للبيانات أو كنت بحاجة إلى أي معلومات أخرى، فسأكون سعيدًا بالمساعدة.

فقط لأكون واضحًا، الخطأ الفعلي الذي تبلغ عنه هنا هو:

في ظل ظروف معينة، يقوم المستخدم أ بتحرير منشور للمستخدم ب، ولا يتم إشعار المستخدم ب؟

بالضبط. لا تظهر الإشعارات هنا ولا في مربع المستخدم (لأن كليهما يعتمد على user_actions):

ومع ذلك، تظهر في الزاوية العلوية اليمنى من المنشور (لأن ذلك يعتمد على post_revisions):

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

هل هذه نسخة مستضافة من قبلنا أم نسخة مستضافة ذاتيًا؟

تحدث إشعاراتنا هنا:

الشرط صارم للغاية:

يتم إنشاء الإشعار هنا:

العنصر الذي قد يتسبب في تعطل هذا هو:

  1. تراكم الوظائف في Sidekiq أو إيقافها مؤقتًا

  2. حالة نادرة جدًا تتمثل في إنهاء الوظيفة في منتصف عملية الإخطار

يمكنني تقديم مثال محدد في مثيل يستضيفه أنت.

هذا المنشور (المعرف 1067) الذي أنشأه المستخدم 3 في 2019-08-03 19:22 بتوقيت UTC، تلقى تعديلاً مني (المستخدم 2) بعد بضع دقائق من إنشائه.

ومع ذلك، لم يتم إنشاء أي user_action من النوع 11 (عكس التعديلات الأخرى الـ 2 التي تلقاها ذلك المستخدم في ذلك اليوم على المنشورات 1001 و1003).

يمكنك رؤيتها بشكل أوضح إذا قمت بتشغيل هذا الاستعلام:

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 3 -- اختر معرف مستخدم
)
select
  up.user_id as my_user_id,
  ua.user_id as target_user_id,
  pr.post_id,
  ua.target_post_id,
  pr.user_id as editor_user_id,
  ua.acting_user_id,
  ua.action_type,
  pr.created_at as edit_created_at,
  ua.created_at as action_created_at
from
  post_revisions pr
  inner join my_user_posts up on up.id = pr.post_id
  and up.user_id != pr.user_id -- لا توجد تعديلات ذاتية
  and pr.user_id != -1 -- لا توجد تعديلات نظام
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- فقط إجراءات التعديل  
WHERE
  pr.created_at between '2019-08-03' and '2019-08-04'
order by
  pr.post_id,
  pr.created_at

لقد قمت بحساب بعض الأرقام، وبغض النظر عن التاريخ، فإن ما بين 7% و25% من تعديلات المنشورات غير الذاتية لا تحتوي على user_action مطابق.

قد يكون هناك خطأ هنا @Nacho_Caballero في النهاية.. انتظر قليلاً. شكرًا لك على المثابرة في هذا الشأن.

كان لدينا هذا الخطأ:

وقد حسّنتُ التنفيذ بهذه الميزة:

كان هناك حالة حدية حيث عندما قام مستخدم بإعجاب منشور لمستخدم آخر ثم قام بتعديله، لم نكن نرسل إشعارًا بشأن التعديل.

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

ممتاز. هذا منطقي جدًا. شكرًا جزيلاً على الإصلاح!