المهام في الخلفية
ما هي
تستخدم ManpowerIQ Hangfire لشيء واحد بالضبط: تشغيل استيراد الموظفين من Excel كمهمة في الخلفية بأسلوب إطلاق-ونسيان كي لا يحجب تحميل كبير طلب HTTP. لا توجد مهام مجدولة أو متكررة في الإصدار v1 — لا اكتساحات بنمط cron، ولا إرسال موقوت من أي نوع.
شطرا تلك الجملة كلاهما يهمّ، فتذكرهما هذه الصفحة بوضوح:
- مهمة استيراد إطلاق-ونسيان — مبنية وحيّة.
- المهام المجدولة/المتكررة — لا وجود لها.
لماذا بُنيت بهذه الطريقة
يحلّل استيراد الموظفين المجمّع ثلاث أوراق جداول بيانات ويُدرِج/يُحدِّث صفوفًا كثيرة؛ فعل ذلك مباشرةً سيقيّد الطلب ويخاطر بانتهاء المهلة. لذا يُدرَج الاستيراد كمهمة Hangfire غير متزامنة تنتقل عبر دورة حياة مُتتبَّعة، بينما يعود الـ API فورًا بسجل مهمة تستطيع الواجهة استطلاعه (الورقة 03 §how-it-works، §decisions). تلك الحالة الوحيدة هي الشيء الوحيد الذي احتاج عاملًا في الخلفية — فوُصِل Hangfire لها ولا شيء آخر.
المهام التي قد يتوقّعها قارئ من التسليم (اكتساح انتهاء الشهادات، إرسال الإشعارات) لم تُبنَ كمهام — انظر المزالق.
كيف تعمل
sequenceDiagram
participant U as User
participant C as ImportsController
participant H as Hangfire queue "imports"
participant R as ImportJobRunner
participant DB as PostgreSQL
U->>C: upload .xlsx
C->>C: synchronous pre-flight (size/ext/schema)
C->>DB: create import_jobs row (Queued)
C->>H: enqueue job
C-->>U: 201 + job record
H->>R: run [Queue("imports")]
R->>DB: Queued → Running → Completed / Failed
U->>C: poll job status / download error report
- مهمة الاستيراد خطّ أنابيب غير متزامن حقيقي على طابور Hangfire
imports، لا مباشرة ولا نسخة وهمية — يحملImportJobRunnerسمة[Queue("imports")]ويقود المهمة منQueued → Running → Completed(الورقة 03 §build-status + §decisions،ImportJobRunner.cs:18،ImportsController.cs:143). - التحقّق التمهيدي متزامن (غير فارغ، ≤10 MB،
.xlsx، فحص المخطط) ويعود 400 قبل إدراج أي شيء (الورقة 03 §rules،ImportsController.cs:67-102). - تعمل المهمة دون سياق HTTP، فتضبط تجاوز مستأجر يدويًا وGUC الخاص بـ Postgres RLS بنفسها؛ وتتخطّى مُهيِّئ الاتصال تحت مزوّد EF InMemory (الورقة 03 edge-cases،
ImportJobRunner.cs:33-51). - حالات دورة الحياة:
Queued → Running → (Completed | CompletedWithErrors | Failed)؛ إلغاء المستخدم (SuperAdmin +imports.view_history) ينقلها إلىCancelledويفحص العامل رمز الإلغاء تعاونيًا بين الصفوف (الورقة 03 §rules).
مزالق / قيود
- لا مهام متكررة/مجدولة. مُتحقَّق منه: grep عن Hangfire
RecurringJob→ لا تطابقات (الإصابات الوحيدة كانت إيجابيات كاذبة لـ EFValueGeneratedOnAddOrUpdate). لا توثّق مجدولًا بنمط cron — لا يوجد واحد. - انتهاء الشهادات بلا اكتساح تلقائي. الشهادات لا تنتقل Active→Expired على مؤقّت؛ لا توجد مهمة في الخلفية لذلك (الورقة 04 §build-status). أي حالة "منتهية" تُحسَب/تُرى فقط حيث يفعل منطق القراءة ذلك، لا تُكتسَح بمهمة.
- الإشعارات بلا مهمة في الواجهة الخلفية. جرس عدّاد المعلّقات هو استطلاع أمامي كل 30 ثانية مقابل عدّادات حيّة؛ لا يوجد نظام إشعارات في الواجهة الخلفية — لا مُرسِل، ولا قالب، ولا مُوزِّع، ولا كيان (الورقة 18 §build-status). ليست مهمة Hangfire.
- مهمة الاستيراد حسّاسة للمزوّد. لأنها تضبط GUC الخاص بالمستأجر/RLS يدويًا وتتفرّع على المزوّد، فقد تتصرّف على نحو مختلف تحت EF InMemory مقابل Postgres — غطِّها باختبار تكامل Postgres، لا مجرّد اختبارات وحدة InMemory (الورقة 03 edge-cases).
- الملف المُحمَّل في الذاكرة فقط (لا يُكتَب على القرص أبدًا)، مُجزّأ بـ SHA-256؛ تكرار خلال 24 ساعة يُحذِّر لكن لا يحجب (الورقة 03 §rules).
حالة البناء
- Available — مهمة استيراد Excel بأسلوب إطلاق-ونسيان عبر Hangfire (
ImportJobRunner، الطابورimports)، من طرف إلى طرف بجدول مهام وإعادة توليد تقرير الأخطاء (الورقة 03 §build-status). - Planned / غائب — أي مهمة مجدولة أو متكررة: اكتساح انتهاء الشهادات (الورقة 04)، إرسال إشعارات الواجهة الخلفية (الورقة 18). لا مهام مجدولة في الإصدار v1.
ذات صلة
- تعدّد المستأجرين — كيف تضبط المهمة GUC الخاص بالمستأجر دون سياق HTTP.
- أوراق الحقائق: 03 (سجل الموظف الرئيسي — الاستيراد)، 04 (المهارات والشهادات)، 18 (الإشعارات).