Ruby on Rails
يخفض تشغيل ريلز عبر تقنية راكتور استهلاك الذاكرة بسبعة أضعاف، لكن تجميد الكائنات والاعتماد على الراكتور الرئيسي لعمليات قواعد البيانات يفرضان زيادة مؤقتة في زمن الاستجابة بنسبة 25%.
AI-assisted summary of Ractors, Rails, and Robots: Automating the Path to Ractor-safety - Andrew Novoselac — original source. Check the original for full context.
Source published:
Key ideas
- تتيح وحدات Ractors تنفيذ كود Ruby بالتوازي الحقيقي داخل عملية واحدة بفضل امتلاك كل راكتور لقفل GVL مستقل مع مشاركة الذاكرة، مما يجمع مزايا العمليات والخيوط. (1:12)
- أظهرت تجارب Shopify المقارنة بين خادم Ractor التجريبي Keno وخادم Puma استهلاك Puma لنحو 7 أضعاف الذاكرة، مقابل زيادة بنسبة 25% في زمن الاستجابة على Keno نتيجة حصر مهام الإدخال والإخراج في راكتور رئيسي. (4:06)
- استخدم فريق Shopify حلقة وكيل ذكاء اصطناعي بتكلفة قرابة 2,000 دولار من أرصدة Claude 3 Opus لاكتشاف وتغطية 67% من قاعدة كود Rails وتأمين 169 مساراً برمجياً في أسبوعين فقط. (15:32)
- ساهم الفريق بأكثر من 100 طلب سحب إلى Rails، مستفيداً من أداة 'فحص العزل' (isolation check) التي تسجل انتهاكات الذاكرة دون إيقاف تشغيل الخادم لمعالجة الثوابت وحالات الفئات. (20:33)
Detailed notes
## Background نُشر هذا العرض التقديمي عبر قناة Ruby on Rails على منصة يوتيوب في الأول من أكتوبر 2026، من مؤتمر Rails World 2026. يقدّم المحاضرة أندرو نوفوسيلاك، مطور البنية التحتية لـ Ruby on Rails في شركة شوبيفاي، متناولاً الجهود التقنية المبذولة لجعل إطار عمل Rails آمناً ومتوافقاً مع نماذج التزامن Ractors لتشغيل خوادم الويب بكفاءة واستهلاك ذاكرة أقل.
## TL;DR يستعرض أندرو نوفوسيلاك الفروق الجوهرية في التزامن بين العمليات والخيوط وRactors في روبي، مبيناً كيف يتيح خادم الويب القائم على Ractor توازياً حقيقياً مع توفير هائل في استهلاك الذاكرة. ويوضح العوائق الهندسية الشديدة التي تحول دون جعل إطار عمل ضخم مثل Rails آمناً مع Ractor بسبب قيود التجميد العميق للأشياء وتتابع الأخطاء غير القابلة للحل اليدوي المتوازي. لمواجهة هذا التعقيد، استعان الفريق بحلقة وكيل ذكاء اصطناعي (AI agent loop) لاختبار وتوليد مسارات برمجية غطت قرابة 67% من كود Rails ورسمت خارطة عمل استكشافية شاملة. وأخيراً، يعرض التعديلات التي تم دمجها بالفعل في نواة الإطار، ونمط فحص العزل الليلي، والتحديات العالقة في الوصول لقواعد البيانات، موجهاً دعوة مفتوحة لمجتمع روبي للمساهمة في تحقيق هذا الهدف.
## Atmosphere & style يتسم اللقاء بطابع هندسي عملي، مفعم بالتواضع والفكاهة الذاتية اللطيفة؛ حيث يكسر أندرو رهبة أول مشاركة له كمتحدث في مؤتمر تقني عبر التواصل الودود مع الجمهور. ينقل العرض إحساساً حقيقياً بالمغامرة الاستكشافية والانتقال من الإحباط الناتج عن "البرمجة الكلاسيكية" وسلسلة الأخطاء المتتابعة إلى الارتياح والإثارة عند تسخير وكلاء الذكاء الاصطناعي لرسم الحلول. تسود الجلسة نبرة واقعية وصادقة تتجنب تجميل العيوب المعمارية وتوازن بين الطموح التقني والتحذيرات البرمجية الدقيقة، مما يمنح المشاهد شعوراً بالحماس للمشاركة في بناء مستقبل روبي.
## Bulletin - [01:12](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=72s) تتيح وحدات Ractors تنفيذ كود Ruby بالتوازي الحقيقي داخل عملية واحدة بفضل امتلاك كل راكتور لقفل GVL مستقل مع مشاركة الذاكرة، مما يجمع مزايا العمليات والخيوط. - [04:06](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=246s) أظهرت تجارب Shopify المقارنة بين خادم Ractor التجريبي Keno وخادم Puma استهلاك Puma لنحو 7 أضعاف الذاكرة، مقابل زيادة بنسبة 25% في زمن الاستجابة على Keno نتيجة حصر مهام الإدخال والإخراج في راكتور رئيسي. - [15:32](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=932s) استخدم فريق Shopify حلقة وكيل ذكاء اصطناعي بتكلفة قرابة 2,000 دولار من أرصدة Claude 3 Opus لاكتشاف وتغطية 67% من قاعدة كود Rails وتأمين 169 مساراً برمجياً في أسبوعين فقط. - [20:33](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1233s) ساهم الفريق بأكثر من 100 طلب سحب إلى Rails، مستفيداً من أداة 'فحص العزل' (isolation check) التي تسجل انتهاكات الذاكرة دون إيقاف تشغيل الخادم لمعالجة الثوابت وحالات الفئات.
## Key takeaways - [01:12](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=72s) تتغلب Ractors على قيود العمليات (العزل التام واستهلاك الذاكرة) والخيوط (غياب التوازي الفعلي بسبب GVL الموحد) بامتلاك كل راكتور لقفل GVL مستقل مع مشاركة الذاكرة. - [04:06](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=246s) الدافع الاقتصادي والهندسي وراء خوادم الويب المعتمدة على Ractor هو خفض التكلفة الباهظة للذاكرة المادية وزيادة التزامن دون التضحية بالموارد. - [07:27](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=447s) يفرض أمان Ractor في لغة Ruby شرط التجميد العميق الصارم لكافة الكائنات ومتغيرات الحالة التابعة لها عبر Ractor.make_shareable. - [09:22](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=562s) تعطلت المحاولات الأولية لتشغيل Rails داخل Ractor بسبب إجراءات التهيئات المرتبطة بـ self وخرائط Concurrent::Map غير القابلة للتجميد في مكتبات مثل Solid Cache. - [12:40](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=760s) الأسلوب البشري اليدوي كان بطيئاً ومعقداً بسبب غياب القدرة على التوازي وظهور خطأ واحد تلو الآخر، مصحوباً بتبديل مستمر ومجهد للسياق البرمجي. - [13:53](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=833s) تم بناء بيئة اختبار موحدة زُوّدت بوكيل ذكاء اصطناعي لتوسيع مسارات التطبيق واكتشاف الأعطال وحلها ذاتياً لإنشاء خارطة طريق استكشافية. - [15:32](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=932s) أظهرت مراجعة بشرية لنحو 200 تعديل أنتجها الوكيل أن 50% منها نظيف وجاهز للدمج، بينما تطلبت 10% جلسات معمارية عميقة. - [18:40](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1120s) حُدد نطاق 'الدعم التجريبي لـ Ractor' للتركيز على مسارات السقالات (scaffold) الأساسية وتأجيل ميزات معقدة مثل Action Cable والتحميل الكسول. - [20:33](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1233s) ابتكر الفريق نمط 'فحص العزل' (isolation check) لجمع تحذيرات الانتهاكات دون إيقاف التنفيذ، وتم ربطه ببناء ليلي يفحص نحو 200 مسار تلقائياً. - [22:15](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1335s) خفّض تجميد الثوابت وحدها ما يقارب 30% من أخطاء العزل، بينما تم اعتماد نمط 'تحديث النسخة المقروءة' لضبط سمات الفئات في Active Record بأمان. - [24:25](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1465s) عمليات الإدخال والإخراج ومجمعات الاتصال غير آمنة لـ Ractors حالياً، مما فرض استخدام مكتبة ractor-dispatch لتنفيذ الاستعلامات عبر الـ Ractor الرئيسي. - [26:13](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1573s) يعد تمرير الاستعلامات إلى الـ Ractor الرئيسي السبب الأساسي لارتفاع زمن الاستجابة (latency)، والحل النهائي يتطلب اتصالاً مباشراً من راكتور الطلب. - [28:15](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1695s) وفّر الفريق واجهة Rails.application.reactorize التجريبية وقوالب جاهزة تتيح لمجتمع Ruby اختبار وتطوير مشاريعهم ومكتباتهم على خوادم مثل Cougar وKeno.
## Detailed walkthrough ### [00:10](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=10s) مقدمة والتعريف بالمتحدث وخطة المحاضرة
بدأ أندرو نوفوسيلاك (Andrew Novoselac) كلمته بالترحيب بالحضور وتقديم نفسه بأسلوب ودود؛ فهو مطوّر يعمل في فريق البنية التحتية لـ Ruby on Rails في شركة Shopify، ويقيم في مدينة هاميلتون بمقاطعة أونتاريو الكندية. أوضح أندرو أنه يعمل في تطوير تطبيقات Rails منذ عام 2018، مشيراً بابتسامة إلى أن هذه هي أول مشاركة له كمتحدث في مؤتمر تقني على الإطلاق، وطلب من الجمهور تشجيعه والتمني له بالتوفيق بقوله: "أرجو منكم الترحيب بي وتمنياتي لي بالتوفيق".
حدّد أندرو بعد ذلك المحاور الأساسية لمحاضرته التي تدور حول جعل إطار عمل Rails متوافقاً وآمناً مع راكتور (Ractor-safe): - استعراض مفهوم خادم الويب القائم على Ractors ودوافع فريق Shopify لخوض هذه التجربة ومحاولة حل مشكلات الكفاءة. - تفكيك أسباب صعوبة جعل إطار عمل ضخم مثل Rails آمناً للعمل مع Ractor، وما الذي تعنيه هذه العملية على المستوى التقني. - شرح كيفية رسم خريطة شاملة لحجم المشكلة ونطاقها بالاعتماد على حلقة وكيل ذكاء اصطناعي (AI agent loop). - استعراض التعديلات البرمجية التي تم تقديمها ودمجها فعلياً في Rails (Upstreaming)، وتوضيح الوضع الحالي والخطوات القادمة في المستقبل.
---
[01:12](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=72s) مقارنة آليات التزامن في Ruby: العمليات، الخيوط، وRactors
انتقل أندرو لتوضيح ماهية Ractors، واصفاً إياها بأنها وحدات بناء أولية للتزامن (concurrency primitives) تتيح التنفيذ البرمجي المتوازي (parallel execution) الحقيقي داخل عملية نظام واحدة (single process). ولتوضيح قيمتها المضافة، عقد مقارنة منهجية بين Ractors وأدوات التزامن التقليدية المتاحة في لغة Ruby، وهي العمليات (Processes) والخيوط (Threads):
1. **العمليات (Processes):** تُشغّل بيئة Ruby الكود داخل عمليات نظام. العمليات متوازية تماماً وقادرة على تشغيل كود Ruby في الوقت نفسه (مثل فتح نافذتين في الطرفية وتشغيل جلستي `rails console` مستقلتين). لكن عيبها الأساسي هو العزل التام للذاكرة وعدم مشاركتها؛ فكل عملية تُحمّل الكود الخاص بها وتحتفظ بمساحة كائنات (object space) منفصلة. 2. **الخيوط (Threads):** يمكن تشغيل خيط واحد أو خيوط متعددة داخل نفس العملية ومشاركة الذاكرة وتحميل الكود مرة واحدة فقط لتصل إليه جميع الخيوط. لكن المشكلة تكمن في غياب التوازي الحقيقي بسبب قفل الآلة الافتراضية العام (GVL - Global VM Lock)؛ حيث يستحوذ خيط واحد فقط على GVL لتنفيذ كود Ruby بينما تظل بقية الخيوط في حالة انتظار وتوقف (suspended). 3. **الراكتورات (Ractors):** تجمع بين أفضل مزايا العمليات والخيوط؛ فهي تسمح بتنفيذ الكود بالتوازي داخل عملية واحدة لأن لكل وحدة Ractor قفل GVL خاصاً بها ومستقلاً عن الأخرى، وتتشارك في الوقت نفسه نفس الذاكرة ونفس الكود والكائنات.
ضرب أندرو مثالاً توضيحياً بحساب خوارزمية فيبوناتشي سريعة (Fast Fibonacci) تستغرق 100 مللي ثانية للعملية الواحدة، مع افتراض الرغبة في تنفيذها 3 مرات: - **باستخدام الخيوط:** عند توزيع الحسابات على ثلاثة خيوط، ينفذ الخيط الأول عمليته خلال أول 100 مللي ثانية بينما ينتظر الخيطان الآخران، ثم ينفذ الخيط الثاني، يليه الخيط الثالث. النتيجة أن البرنامج يستغرق 300 مللي ثانية إجمالاً، لأن خيطاً واحداً فقط ينفذ كود Ruby في اللحظة ذاتها. - **باستخدام Ractors:** تمتلك كل وحدة Ractor قفل GVL خاصاً بها، مما يمكّن الوحدات الثلاث من إتمام العمليات الحسابية بالتوازي في الوقت عينه، لينتهي التنفيذ بالكامل خلال 100 مللي ثانية فقط بدلاً من 300.
أشار أندرو إلى خلفية تاريخية سريعة؛ إذ ظهرت Ractors كميزة تجريبية لأول مرة مع إطلاق Ruby 3.0 في عام 2020، وبفضل جهود مهندسي Shopify ومجتمع Ruby الأوسع، شهدت تحسينات جذرية في Ruby 4.0 مع وعود بالمزيد في Ruby 4.1، لتصل إلى مرحلة النضج والجاهزية للاختبار الحقيقي في بيئات الإنتاج (Production).
```mermaid flowchart TD accTitle: مقارنة نماذج التزامن في روبي accDescr: مخطط يوضح الفرق بين العمليات والخيوط والراكتور من حيث التوازي ومشاركة الذاكرة
subgraph Processes["العمليات (Processes)"] P1["عملية مستقلة 1<br/>ذاكرة معزولة"] P2["عملية مستقلة 2<br/>ذاكرة معزولة"] P1 -.->|"توازي كامل / لا مشاركة ذاكرة"| P2 end
subgraph Threads["الخيوط (Threads)"] T_MEM["ذاكرة مشتركة واحدة"] T1["خيط 1 (يمتلك GVL)"] T2["خيط 2 (معلق ينتظر GVL)"] T_MEM --- T1 T_MEM --- T2 end
subgraph Ractors["الراكتورات (Ractors)"] R_MEM["ذاكرة مشتركة موحدة"] R1["Ractor 1 (GVL مستقل)"] R2["Ractor 2 (GVL مستقل)"] R_MEM === R1 R_MEM === R2 end ```
---
[04:06](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=246s) فكرة خادم الويب القائم على Ractor وتجربة الأداء مع تطبيق Writebook
انتقل الحديث إلى التطبيق العملي للتقنية داخل Shopify عبر بناء خادم ويب تجريبي يعتمد على Ractors. استعرض أندرو المعضلة الهندسية في خوادم الويب الحالية: - **الخوادم متعددة الخيوط (Multithreaded):** تعمل بعملية واحدة وعدة خيوط، وتضطر لزيادة الخيوط لخدمة طلبات متزامنة أكثر، مما يؤدي إلى زيادة زمن الاستجابة (latency) بسبب تناوب الخيوط واصطفافها في طوابير الانتظار لنيل الـ GVL. - **الخوادم متعددة العمليات (Preforking):** الحل التقليدي المعتمد تاريخياً في Shopify والمجتمع، وفيه تُنشأ عملية رئيسية تتفرع لعدة عمليات فرعية تخدم الطلبات بالتوازي. ورغم وجود تقنية "النسخ عند الكتابة" (Copy-on-Write) على مستوى نظام التشغيل لمشاركة بعض الصفحات في البداية، إلا أن صفحات الذاكرة تتباعد وتفسد مع استمرار العمل، مما يجعل العمليات معزولة تماماً. وبناءً عليه، تعني زيادة التزامن زيادة عدد العمليات، مما يتسبب في استهلاك ضخم للذاكرة.
شدد أندرو على أن تكلفة الذاكرة المادية أصبحت مرتفعة للغاية في الوقت الحاضر، قائلاً بنبرة ساخرة: "لا أعلم إن كنتم تتابعون الأخبار، لكن تكلفة الذاكرة أصبحت باهظة جدًا هذه الأيام". لذا تسعى Shopify لاستغلال العتاد المدفوع ثمنه بأعلى كفاءة ممكنة عبر خدمة أكبر عدد من الطلبات بأقل استهلاك للذاكرة. من هنا وُلدت الفرضية: "أن خادم الويب القائم على Ractor يمكن أن يسمح لنا بزيادة التزامن في نظامنا دون زيادة الذاكرة أو زمن الاستجابة".
لاختبار هذه الفرضية، بنى الفريق تجربة باستخدام تطبيق Writebook (تطبيق التدوين وحفظ الدفاتر مفتوح المصدر من Basecamp): - قاموا بجعل جزء صغير من التطبيق آمناً لـ Ractor وربطه بخادم ويب تجريبي يُدعى **Keno** (يعمل بعملية واحدة و9 معالجات Ractor)، وقارنوا أدائه بخادم **Puma** الكلاسيكي (مضبوط على 9 عمليات). - **الذاكرة:** حقق خادم Ractor توفيراً هائلاً؛ حيث استهلك خادم Puma قرابة 7 أضعاف الذاكرة مقارنة بـ Keno. - **زمن الاستجابة (Latency):** سُجلت زيادة بنسبة 25% في زمن الاستجابة لصالح Puma (أي أن Ractor كان أبطأ بنسبة 25%). - ترك أندرو سبب زيادة زمن الاستجابة مؤقتاً "كتمرين للمشاهد ليفكر في سببه" قبل أن يعود لشرحه لاحقاً في المحاضرة، داعياً الجمهور للاطلاع على المقال التقني المنشور على مدونة Shopify الهندسية والذي يوثق كافة تفاصيل وأرقام هذه التجربة.
---
[07:27](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=447s) ما المقصود بـ "Ractor-safe" وتحدي التجميد العميق للبيانات
طرح أندرو السؤال الجوهري الذي قد يتبادر لذهن أي مهندس متشكك: "ما المشكلة إذن؟ ما الذي يجعل هذا العمل صعباً إلى هذا الحد؟" وأجاب بالاعتراف بأنه استخدم مصطلح "Ractor-safe" دون تعريفه بدقة، منتقلاً لتفكيك المعنى الداخلي لأمان Ractor في بيئة Ruby.
تتشارك وحدات Ractor الذاكرة بالفعل، لكن Ruby تفرض قيداً عزل صارماً: **أي كائن يتم مشاركته بين وحدات Ractor يجب أن يكون مُجمّداً تجميداً عميقاً (Deeply Frozen)**. لا يكفي تجميد الكائن الخارجي فقط (`freeze`)، بل يجب تجميد كافة متغيرات الحالة ومثيلاتها (instance variables)، ومتغيرات الكائنات التابعة لها وصولاً إلى آخر عقدة في شجرة الكائن بالكامل.
```ruby # مثال يوضح أخطاء العزل وضرورة التجميد العميق:
# 1. جدول تجزئة قابل للتعديل يسبب خطأ عزل config = { key: "value" } Ractor.new { config[:key] } # => Ractor::IsolationError (can not access non-shareable objects)
# 2. تجميد سطحي غير كافٍ إذا احتوى كائنات قابلة للتعديل config = { key: ["bar"] }.freeze Ractor.new { config[:key] } # => Ractor::IsolationError (المصفوفة داخل التجزئة لا تزال قابلة للتعديل)
# 3. الحل: التجميد العميق لجعل الكائن قابلاً للمشاركة config = { key: ["bar"] } Ractor.make_shareable(config) Ractor.new { config[:key] } # يعمل بنجاح وبأمان تام ```
أوضح أندرو الخطوات عبر المثال البرمجي: - إذا كان هناك ملف تهيئة في صورة جدول تجزئة (Hash)، وحاول Ractor جديد الوصول إليه مباشرة من Ractor الرئيسي المنشئ له، ستلقي لغة Ruby خطأ عزل (`Ractor::IsolationError`) لأن الـ Hash قابل للتعديل (mutable). - تجميد الـ Hash فقط يحل المشكلة جزئياً إذا كانت قيمه بدائية؛ ولكن إذا احتوى على كائنات مركبة قابلة للتعديل (مثل مصفوفة بداخلها نصوص)، فإن محاولة الوصول إليها ستُسفر عن الخطأ ذاته لأن المصفوفة الداخلية لم تُجمد. - القاعدة تفرض تجميد كل شيء؛ ولتسهيل ذلك توفر Ruby الدالة المساعدة `Ractor.make_shareable`. - اختتم أندرو هذا الجزء بالإشارة إلى الكلمة الافتتاحية التي قدمها آرون باترسون (Aaron Patterson) في مؤتمر العام السابق، والتي شرح فيها أساسيات كائنات Ractor وآليات جعل العناصر قابلة للمشاركة بالتفصيل، ناصحاً الحضور بالرجوع إليها لفهم الأسس النظرية التحتية لمنظومة المشاركة.
[09:22](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=562s) محاكاة جعل تطبيق Rails آمنًا مع Ractor وسلسلة الأخطاء المتتابعة
يوضح أندرو نوفوسيلاك ما يعنيه عمليًا جعل إطار عمل Rails متوافقًا وآمنًا للاستخدام مع ميزة Ractor في لغة روبي (Ractor-safe). المفهوم الأساسي في جوهره يبدو مباشرًا للغاية: يبدأ بتشغيل التطبيق، ثم استدعاء دالة `Ractor.make_shareable` على كائن تطبيق Rails نفسه—وهو الكائن المسؤول فعليًا عن تلقي الطلبات والاستجابة لها—وبعد ذلك، يتم إنشاء Ractor جديد واستدعاء التطبيق بداخله لمعالجة معلومات الطلب. ولكن للإجابة عن التساؤل البديهي: "ما مدى صعوبة ذلك؟"، يفضل أندرو استعراض ما يحدث خطوة بخطوة بدلًا من الاكتفاء بالشرح النظري. ورغم تحذيرات زملائه الشديدة من إجراء عرض توضيحي مباشر (Live Demo) على المسرح تجنبًا للمفاجآت غير السارة، فإنه يدعو الحضور إلى تخيل إجراء العرض مباشرة: إنشاء تطبيق Rails جديد، وفتح سطر أوامر وحدة التحكم (Console)، واستدعاء دالة `Ractor.make_shareable`، ومراقبة النتيجة.
بمجرد تنفيذ هذا الاستدعاء، تنهار التجربة سريعًا ويظهر الخطأ الأول: > "خطأ: لا يمكن مشاركة الإجراء `self` من ملف `rails/initializable.rb` في السطر 44."
عند تفحص الكود المسبب، يتبين أن تطبيقات Rails ومحركاتها (Rails engines) تعرّف مهيئات (Initializers) تُخزن داخل بنية بيانات تستخدم جداول تجزئة (Hashes). تحتوي هذه الجداول على إجراءات برمجية (Procs) افتراضية؛ بحيث إذا طُلب منها مفتاح غير موجود، يقوم الـ Proc تلقائيًا بتعيين قيمة فارغة لذلك المفتاح. المشكلة الجوهرية تكمن في أن هذا الـ Proc يرتبط ضمنيًا بـ `self`، ولكي يصبح الكود آمنًا وقابلًا للمشاركة في بيئة Ractor، يجب أن يكون كل كائن يشير إليه الإجراء آمنًا وغير قابل للتعديل أيضًا. لكن التغلب على هذه العقبة ممكن منطقيًا: فبمجرد إقلاع تطبيق Rails، تكون كافة المُهيئات قد حُمّلت ونُفّذت بالفعل، ولا يُفترض بالتطبيق إنشاء مهيئات جديدة في خضم معالجة طلبات الويب—ويعلق أندرو ساخرًا بأنه "رأى بعض الأمور الغريبة في تطبيقات Rails، لكن نأمل ألا نُنشئ مُهيئات أثناء معالجة الطلبات". بالتالي، يمكن ببساطة التخلص من هذا الإجراء الافتراضي وتجميد (freeze) المجموعة بالكامل لتجاوز العقبة الأولى.
عند إعادة المحاولة واستدعاء `make_shareable` مجددًا، يظهر خطأ جديد على الفور: `undefined method freeze for Concurrent::Map`. خرائط `Concurrent::Map` غير قابلة للتجميد في روبي، وبالتالي تُعد غير آمنة في بيئة Ractor. العقبة الإضافية هنا كانت غياب السياق؛ إذ لا تُظهر رسالة الخطأ سطر الكود أو الكائن الذي يحتوي على هذه الخريطة. ولمعالجة هذا القصور في رسائل أخطاء Ractor غير المرضية، قام فريق أندرو في Shopify بتقديم تصحيحات (Patches) في شجرة تطوير لغة روبي (مستهدفة الإصدارات القادمة)، بحيث تُظهر رسالة الخطأ المسار الهرمي للكائن ومتغيرات الحالة (Instance variables) صعودًا حتى قمة شجرة الكائنات. وباستخدام هذا التتبع، تبيّن أن مصدر الخريطة يعود إلى مكتبة `Solid Cache`. تعقيد المشكلة هنا يرجع إلى أن `Solid Cache` ليست جزءًا مدمجًا في نواة Rails، بل جوهرة (Gem) مستقلة تعتمد بدورها على `Active Record`، مما يطرح معضلة معقدة حول كيفية جعل جوهرة خارجية آمنة مع Ractor قبل أن يصبح الإطار الأساسي نفسه آمنًا.
- **الخطأ الأول:** فشل مشاركة الـ Proc في `rails/initializable.rb:44` بسبب ارتباطه بكائن `self`. - **حل المشكلة الأولى:** إسقاط الـ Proc الافتراضي وتجميد جدول التجزئة بعد اكتمال مرحلة الإقلاع. - **الخطأ الثاني:** عدم قابلية `Concurrent::Map` للتجميد داخل جوهرة `Solid Cache`. - **تحسين رسائل روبي:** مساهمات برمجية من فريق Shopify لإظهار التسلسل الهرمي للكائنات في أخطاء Ractor. - **الخطأ الثالث:** خطأ جديد ينبثق من `Action Cable` بمجرد الالتفاف حول المشاكل السابقة.
---
[12:40](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=760s) تحديات الحل اليدوي وعصر "البرمجة الكلاسيكية"
يكشف هذا التتابع السريع للأخطاء عن جوهر الصعوبة الهندسية التي واجهها الفريق. تكمن المعضلة الأساسية في أن هذه العملية **غير قابلة للتنفيذ بالتوازي** إطلاقًا على المستوى البشري؛ إذ لا يعرض النظام سوى خطأ واحد في كل محاولة، ويتحتم على المطور تشخيصه وإصلاحه أو الالتفاف عليه فقط ليصطدم بالخطأ الذي يليه. نتيجة لذلك، يصبح من المستحيل رؤية "خط النهاية" أو تقدير حجم العمل المتبقي، سواء كان المتبقي 10 أخطاء، أو 100، أو 1000 خطأ مخفي خلف السلسلة.
يُضاف إلى ذلك الإرهاق الذهني الناجم عن التبديل المستمر للسياق (Context Switching). ففي غضون دقائق معدودة، ينتقل المطور من التعامل مع مهيئات إقلاع Rails، إلى مكتبة تخزين مؤقت خارجية (`Solid Cache`)، ثم مباشرة إلى نظام اتصالات الويب الحية (`Action Cable`). ويجد المهندس نفسه مجبرًا على القفز عبر مكونات الإطار المعقد بترتيب عشوائي يفرضه مسار استدعاء الأخطاء، وكل هذا العناء يحدث حتى قبل الوصول إلى التحديات البرمجية الحقيقية؛ أي مرحلة معالجة طلبات الويب الفعلية وما تتطلبه من الوصول إلى قواعد البيانات، وعرض القوالب (Rendering)، وتسجيل البيانات (Logging)، وإدارة الذاكرة المؤقتة.
يوضح أندرو أن فريقه في Shopify حاول في البداية خوض هذه المهمة يدويًا بالكامل، فيما وصفه ديفيد هاميلتون بـ "العصر القديم للبرمجة"، ويفضل أندرو تسميته "البرمجة الكلاسيكية". ولكن مع بطء التقدم الشديد وتكرار العقبات غير المتوقعة، بات واضحًا للجميع أن اتباع هذا النهج التقليدي لن يجدي نفعًا، ولا بد من البحث عن أسلوب جديد ومختلف جذريًا.
---
[13:53](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=833s) الاستعانة بوكلاء الذكاء الاصطناعي وبناء بيئة الاختبار (Harness)
مع التطور المتسارع في قدرات وكلاء الذكاء الاصطناعي (AI Agents)، طرح الفريق فكرة الاعتماد على وكيل ذكي للمساعدة في رسم هذه الخارطة المعقدة. الميزة الأكبر لوكلاء الذكاء الاصطناعي—بحسب تعبير أندرو المازح—هي أنهم "لا يهتمون إلا بالمال ولا يتعبون أبدًا"؛ فما دمت تزود النظام بوحدات الحوسبة والرموز (Tokens)، فلن يطلب استراحة غداء، ولن يشعر بالملل أو تشتت الانتباه، بل سيواصل تكرار المحاولات بلا كلل.
لبناء هذه المنظومة، أنشأ الفريق ما أطلقوا عليه "تسخير المستودع" (Repo Harness). وهو مستودع برمجي موحد ومغلق يحتوي على كافة التبعيات الضرورية: شجرة كود Ruby، ومكتبة Rack، ومستودع Rails، إضافة إلى تطبيق وهمي (Dummy App) مرتبط بهذه التبعيات. زُوّد الوكيل بمجموعة من المهارات والأدوات البرمجية، مثل القدرة على تشغيل الاختبارات، وإعادة بناء لغة روبي من المصدر إذا أدخل تعديلات عليها، وتحديث بيئة التطوير لنفسه تلقائيًا.
```mermaid flowchart TD accTitle: دورة عمل وكيل الذكاء الاصطناعي لتأمين Rails مع Ractors accDescr: يوضح الرسم التكرار الآلي للوكيل عبر أربع مراحل من التحميل حتى توسيع الوظائف داخل بيئة المستودع الموحد.
subgraph Harness["بيئة المستودع الموحد (Repo Harness)"] Deps["تبعيات Ruby + Rack + Rails + Dummy App"] Tools["أدوات الوكيل: تشغيل الاختبارات وإعادة بناء Ruby"] end
subgraph Loop["حلقة التكرار المستمرة (Agent Loop)"] Step1["1. تعديل الكود لجعل التطبيق قابلاً للمشاركة (make_shareable)"] Step2["2. معالجة الطلبات وإرجاع استجابة 200 OK عبر Ractor"] Step3["3. توليد مسارات جديدة وكسر بيئة Ractor عمدًا"] Step4["4. تصحيح الأعطال وجعل المسارات الجديدة Ractor-safe"] end
Harness --> Step1 Step1 --> Step2 Step2 --> Step3 Step3 --> Step4 Step4 -->|"تكرار لا نهائي"| Step3 ```
أما خطة العمل التي كُلف بها الوكيل، فكانت تتلخص في حلقة تكرارية واضحة: 1. الاستمرار في تجربة التعديلات حتى ينجح التطبيق في استدعاء `Ractor.make_shareable`. 2. مواصلة التكرار حتى يتمكن التطبيق من الرد على طلب HTTP باستجابة ناجحة `200 OK` من داخل Ractor. 3. الشروع في إضافة وظائف ومسارات جديدة تكسر التوافق مع Ractor، ثم ابتكار حلول برمجية لإصلاحها وجعلها تعمل. 4. الاستمرار في هذه الدورة التوسعية والتصحيحية إلى ما لا نهاية حتى يصدر أمر بالتوقف.
---
[15:32](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=932s) نتائج التجربة: رسم خارطة طريق لأمان الـ Ractor
أسفرت التجربة عن نتائج مذهلة تجاوزت التوقعات؛ حيث استخرج الوكيل تقريرًا تفصيليًا يوضح أن التطبيق الوهمي بات يحتوي على **169 مسارًا برمجياً (Routes)** تعمل بالكامل داخل Ractors، محققًا تغطية بلغت حوالي **67% من قاعدة كود إطار عمل Rails**، وموزعة بدقة عبر مختلف مكونات النظام. وعلى الصعيد التشغيلي، كلف هذا التشغيل ما يقارب **2,000 دولار** من أرصدة نموذج Claude 3 Opus (أفضل نموذج متوفر آنذاك)، وتطلب حوالي أسبوع واحد فقط من العمل الهندسي البشري لإعداد البيئة ومراقبتها. أجرى الفريق بعد ذلك دورات إضافية للتحقق من إمكانية إعادة إنتاج النتائج ولتحسين بعض الحلول المقترحة.
وسط أجواء الاحتفال بإنجاز المهمة—وعرض شعار "Toronto Ractors" التورنتوي الساخر الذي يعتمده مهندسو Shopify كشعار غير رسمي لمشروع Ractor—تطرق أندرو إلى السؤال الحتمي الذي يطرحه المهندسون المنتمون لنادي "أنا ما زلت أقرأ الكود": هل راجع أحد هذا الكود المولد آليًا بالفعل؟ يؤكد أندرو أنه قضى أسبوعين كاملين في قراءة كل سطر كود أنتجه الوكيل، حيث راجع النموذج النهائي الذي تضمن حوالي **200 تعديل داخل إطار عمل Rails**، تركز معظمها في جوهر النظام: `Action View`، و`Active Record`، و`Action Pack`.
| تصنيف التعديلات | النسبة | التقييم الهندسي وطبيعة التعديل | |:--- |:--- |:--- | | **تعديلات نظيفة وبسيطة** | 50% | حلول واضحة، تبدو ممتازة وجاهزة للدمج (Merge) المباشر في الإطار. | | **حلول في الاتجاه الصحيح** | 40% | أفكار سليمة تمامًا تحتاج فقط لتوجيه بشري طفيف أو تنظيف برمجي قبل الدمج. | | **مسائل معمارية وتصميمية** | 10% | أجزاء معقدة تتطلب جلسات تصميم مخصصة بين البشر لتحديد المعمارية المناسبة لـ Rails. |
في المقابل، لم يخلُ عمل الوكيل من عيوب تعكس طبيعته الآلية؛ فلم يتردد في كتابة دوال ضخمة تتجاوز 5,000 سطر، أو تكرار نفس النمط البرمجي عشرات المرات عبر الكود بدلًا من صياغة واجهة برمجية (API) مجردة وأنيقة—وهي القيمة التي يحرص عليها مجتمع Rails بشدة. كما لجأ الوكيل أحيانًا إلى عزل أخطاء Ractor وتجاوزها بأساليب التفافية قسرية. لكن أندرو يشدد على أن الهدف الأساسي لم يكن الحصول على كود مثالي جاهز للإنتاج فورًا، بل توفير **خارطة طريق استكشافية** لمشكلة ضخمة كان يُعتقد أنها ستستغرق عامًا كاملًا من البحث البشري المضني لفهم أبعادها، بينما وفر الوكيل تصنيفًا شاملاً لنطاق العمل في غضون أسبوعين فقط.
---
[18:40](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1120s) المرحلة الأولى: تحديد نطاق الدعم التجريبي (Experimental Ractor Support)
بعد امتلاك النموذج الأولي والخارطة الشاملة، انتقل الفريق إلى التفكير في الخطوات العملية للمساهمة في النسخة الرئيسية من Rails (Upstreaming). وبدلًا من محاولة دمج هذا الحجم الهائل من التغييرات دفعة واحدة، استقر الرأي على استخلاص نطاق عملي ومحدد يمثل المرحلة الأولى، أُطلق عليه "الدعم التجريبي لـ Ractor" (Experimental Ractor Support).
يهدف هذا النطاق الأولي إلى تمكين المطور من إنجاز المهام الأساسية التالية بنجاح تام: - إنشاء تطبيق جديد تمامًا عبر الأمر المعتاد `rails new`. - إنشاء مسارات ونماذج قياسية باستخدام السقالات البرمجية (`scaffold`). - جعل تطبيق Rails قابلاً للمشاركة بالكامل عبر `Ractor.make_shareable(Rails.application)`. - تشغيل واستجابة كافة هذه المسارات المولدة من داخل كائنات Ractor مستقلة.
يتميز هذا النطاق بكونه واقعيًا وقابلًا للإنجاز وسهل القياس، وفي الوقت نفسه يغطي المكونات الحيوية لأي تطبيق ويب حقيقي: مشاركة الذاكرة، والتخاطب مع قاعدة البيانات، وتسجيل الأحداث، وعرض واجهات المستخدم، مع تجنب التعقيدات الطرفية الأخرى وتأجيلها إلى مراحل لاحقة بعد نضوج أنماط الأمان البرمجية في قلب الإطار.
[19:42](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1182s) حدود النطاق والابتعاد عن فخ حلقة الذكاء الاصطناعي
يوضح أندرو نوفوسيلاك أن الفريق قرر حصر النطاق بدقة في هذه المرحلة؛ إذ لم يتم تعديل Action Cable، أو معالجة المهام الخلفية، أو التبعيات الخارجية مثل Solid Cache، كما تُرك وضع التطوير (development mode) دون مساس بسبب اعتماده العميق على التحميل الكسول (lazy loading). وعندما حان وقت نقل التعديلات من النموذج الأولي العملاق وغير المنظم إلى الفرع الرئيسي لـ Rails، واجه الفريق معضلة تحديد ما يحتاجونه فعليًا للدمج في المصدر الرئيسي.
كان الإغراء الأولي حاضرًا بقوة داخل الفريق: الاعتماد على حلقة وكيل ذكاء اصطناعي إضافية ("حلقة وكيل أخرى فقط، يا صديقي") لتمرير النطاق الجديد ومقارنته بالنموذج القديم لاستخراج التغييرات المطلوبة تلقائيًا. إلا أن أندرو شعر بأنهم بدأوا "يغرقون في تعليمات الذكاء الاصطناعي البرمجية"، حيث باتت كل دورة جديدة تفرض عبئًا إدراكيًا ومعرفيًا ثقيلًا لمجرد قراءة وفهم وتتبع ما ينتجه النموذج. قادهم هذا الشعور إلى البحث عن أداة أكثر ثباتًا وقابلية للتكرار وتُعطي نتائج حتمية محددة.
[20:33](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1233s) ابتكار فحص العزل (Isolation Check) وتتبع الأخطاء يوميًا
لتحقيق الدقة المطلوبة، ابتكر الفريق مفهوم "فحص العزل" (isolation check) في الـ Ractor. هذا النمط هو Ractor خاص ومُعدّل لا يملك خصائص التوازي الحقيقية، لأنه بدلًا من إيقاف البرنامج وإلقاء خطأ عزل صارم بمجرد لمس حالة غير آمنة، يقوم بإصدار تحذيرات واستكمال التنفيذ. هذا التغيير البسيط يسمح بجمع وحصر جميع انتهاكات العزل التي تحدث أثناء دورة حياة الطلب الواحد كاملة دون أن يتعطل السيرفر عند أول عقبة. فعلى سبيل المثال، إذا تم استدعاء ثابت مثل `foo` ثلاث مرات، يتلقى المطور ثلاثة تحذيرات مفصلة ثم يُطبع "Hello world" كالمعتاد.
تم رفع هذا المقترح إلى نظام تتبع الأخطاء والميزات الرسمي للغة روبي، ويأمل الفريق أن يصبح جزءًا أساسيًا من روبي 4.1. ولبناء مسار عملي، ربط الفريق هذه الميزة ببناء تجريبي ليلي (nightly build) يقوم بسحب أحدث تغييرات Rails، وتشغيل ما يقارب 200 مسار طلب فريد، وجمع الانتهاكات وتصنيفها تلقائيًا وفق مكان حدوثها في الكود وتتبع الأخطاء (stack traces). وقد منحهم هذا الجمع بين النموذج الأولي للذكاء الاصطناعي (الذي قدّم أنماط الحلول) وفحص العزل الليلي (الذي حدد المشاكل الحية يوميًا) رؤية كاملة للانطلاق في العمل الفعلي.
```mermaid flowchart TD accTitle: خط أنابيب فحص العزل الليلي لـ Rails accDescr: يوضح الرسم كيفية سحب الكود وفحص المسارات عبر راكتور فحص العزل لجمع التحذيرات وتصنيفها.
subgraph NightlyBuild ["البناء التجريبي الليلي"] A["سحب آخر تحديث لـ Rails"] --> B["تهيئة التطبيق وتوليد المسارات (~200 مسار)"] B --> C["تنفيذ الطلبات داخل راكتور فحص العزل"] end
subgraph DiagnosticOutput ["النتائج والتشخيص"] C -->|"إصدار تحذيرات دون إيقاف التنفيذ"| D["تجميع أخطاء العزل"] D --> E["تصنيف الأخطاء حسب الملف وتتبع الكود"] end ```
[22:15](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1335s) تدفق طلبات السحب وأنماط الإصلاح: الثوابت وحالة الفئات
خلال أشهر الصيف، أرسل فريق البنية التحتية في شوبيفاي أكثر من 100 طلب سحب (Pull Request) إلى Rails لتعزيز أمان الـ Ractor، وتراوحت تلك التعديلات بين البسيطة والمعقدة:
- **تجميد الثوابت (Freezing Constants):** كانت البداية مع أسهل المشاكل، حيث احتوى Rails على العديد من الثوابت المعرفة كمصفوفات أو جداول تجزئة قابلة للتعديل دون داعٍ حقيقي، مما يسبب أخطاء عزل فورية عند الوصول إليها من Ractor آخر. أدى تجميد هذه الثوابت عبر الكود واستخدام قواعد RuboCop المخصصة إلى خفض ما يقرب من 30% من إجمالي الأخطاء فورًا. - **سمات الفئات ونمط تحديث النسخة المقروءة (Copy-on-Write Pattern):** تمتلك نماذج Active Record سمات مثل مصفوفات الحقول المخصصة للقراءة فقط. اقترح وكيل الذكاء الاصطناعي في البداية دالة ضخمة تتجاوز 5000 سطر تمر على التطبيق بالكامل لتجميد كل شيء قبل الإغلاق، لكن الفريق رفضها لصعوبة إدارتها ولأنها تخلق حالة يدوية هشة تتطلب تذكر استدعائها. - **التنفيذ العملي للنمط:** اعتمد الفريق بديلًا أسماه نمط "تحديث النسخة المقروءة"؛ حيث تكون المصفوفات مجمّدة افتراضيًا، وعند الرغبة في إضافة عناصر، تؤخذ نسخة منها، تُضاف العناصر، ثم تُجمّد النسخة الجديدة ويُعاد تعيينها للسمة، مما يضمن أمانها عبر كل مراحل دورة حياة التطبيق (وهو نمط فصله زميله هارلي في مقال تقني).
[24:25](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1465s) التحدي المعقد: الوصول لقاعدة البيانات وعمليات الإدخال/الإخراج
شكّل الوصول لقاعدة البيانات العقبة الكبرى لأن عمليات الإدخال والإخراج (I/O) غير آمنة للمفاعلات بطبيعتها ولا يمكنها عبور حدود الـ Ractor مباشرة، فضلاً عن أن مجمعات الاتصال (connection pools) هي كائنات متغيرة الحالة تتبع من يستأجر الاتصالات في أي لحظة. لحل هذه الأزمة مؤقتًا، استخدم الفريق جوهرة تُدعى `ractor-dispatch` تسمح بتمرير المهام غير الآمنة لتُنفّذ داخل الـ Ractor الرئيسي ثم إعادة النتائج إلى راكتور الطلب.
```mermaid flowchart LR accTitle: دورة حياة طلب قاعدة البيانات عبر Ractor Dispatch accDescr: توضح الخطوات انتقال العمل من راكتور الطلب إلى الراكتور الرئيسي للتعامل مع قاعدة البيانات ثم العودة.
subgraph RequestRactor ["راكتور معالجة الطلب"] Req1["تنفيذ البرمجيات الوسيطة"] --> Req2["بناء استعلام SQL"] Req3["تهيئة نموذج Active Record"] --> Req4["عرض صفحة HTML"] end
subgraph MainRactor ["الراكتور الرئيسي"] MainExec["تنفيذ استعلام SQL والاتصال بقاعدة البيانات"] end
Req2 -->|"تمرير الاستعلام (Dispatch)"| MainExec MainExec -->|"إعادة النتائج المجمّدة"| Req3 ```
يتم تنفيذ معالجة الطلب، والبرمجيات الوسيطة (middleware)، وبناء استعلام الـ SQL على راكتور الطلب، ولكن لحظة تنفيذ الاستعلام الفعلي، يُرسل العمل إلى الـ Ractor الرئيسي الذي يمتلك الاتصال بقاعدة البيانات، ومن ثم تُعاد النتائج إلى راكتور الطلب لتهيئة الكائنات وعرض الـ HTML.
[26:13](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1573s) ضريبة التأخير (Latency) والحلول المستقبلية
يكشف هذا النمط بوضوح سبب زيادة زمن الاستجابة (latency) عند استخدام المفاعلات؛ فالـ Ractor الرئيسي يعمل كخيط تنفيذ أحادي لا يستطيع معالجة سوى استعلام واحد في الوقت ذاته. إذا وصل طلبان (GET و POST) في الوقت نفسه، سيضطر أحدهما للانتظار حتى ينتهي الـ Ractor الرئيسي من استعلام الطلب الأول، مما يُحدث حظرًا وتأخيرًا متراكمًا، إضافة إلى تكلفة نقل الرسائل ومشاركتها بين المفاعلات نفسها (inter-ractor communication).
- **الرؤية المستقبلية:** الهدف النهائي هو تشغيل 100% من الكود على راكتور الطلبات، وأن تمتلك الاتصالات مفاعلات خاصة بها يستطيع راكتور الطلب فحصها والتحكم بها مباشرة، لكن هذا يتطلب إعادة هيكلة جذرية داخل Rails. - **عوائق إضافية:** وجود حالات كسولة في Active Record تُهيأ فقط عند أول اتصال بقاعدة البيانات ويجب ضبطها على الـ Ractor الرئيسي، بالإضافة إلى مكتبات غير متوافقة مع الـ Ractors حتى الآن، وعلى رأسها مكتبة `Nokogiri`.
[28:15](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1695s) كيفية تجربة المفاعلات في Rails محليًا
أتاح الفريق واجهة جديدة للبدء في الاختبار تسمى `Rails.application.reactorize`، والتي تدمج كافة الخطوات التمهيدية الإلزامية قبل تجميد التطبيق وجعله قابلاً للمشاركة بين المفاعلات (shareable). ويُنبه أندرو إلى أن استدعاء هذه الدالة يطبع تحذيرًا صريحًا بأن دعم المفاعلات لا يزال تجريبيًا وعرضة للتغيير بالكامل، بما في ذلك اسم التابع نفسه ("لذا لا تعتاد عليه").
يمكن للمطورين تجربة هذه الميزة عمليًا عبر استخدام خوادم ويب مبنية على الـ Ractors؛ حيث رشح خادم `Cougar` لكونه بسيطًا وخفيفًا للغاية ويسهل قراءة كامل كوده البرمجي، وخادم `Kino` الذي يتميز بثرائه البرمجي ودعمه لميزات أوسع، إلى جانب توفير قالب (template) جاهز لبدء المشاريع واختبار السلوك بأنفسهم.
[29:00](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1740s) قالب Rails المهيأ لـ Ractor وتجربة الخادم المباشرة
يشرح أندرو نوفوسيلاك كيفية البدء العملي بتجربة هذه التقنية، مشيرًا إلى توفير قالب لتطبيق Rails مهيأ بالكامل ليعمل بتوافق مع Ractor. يتضمن هذا القالب إعدادات خاصة ومحددة، مثل تخطي حزم Solid Gems الافتراضية، وتفعيل بعض الميزات الضرورية الأخرى لضمان تشغيل دعم Ractor بشكل صحيح. ولتسهيل الوصول إلى هذا السكربت، عُرض رمز استجابة سريعة (QR code) على الشاشة يحتوي على الرابط المباشر للقالب، والذي وصفه بأنه طويل نوعًا ما. وبمجرد تشغيل هذا السكربت، يبدأ خادم الويب بالعمل، وعند إرسال طلبات حقيقية إليه، يتم معالجتها وتقديم الاستجابة مباشرة عبر الـ Ractor الرئيسي، وهو ما يمثل خطوة مثيرة وملموسة للغاية في هذا المسار.
ولم يخلُ هذا الطرح من لمسة فكاهية وتحذير أمني في آنٍ واحد؛ حيث حثّ الحضور بابتسامة على قراءة محتوى القالب وفحصه جيدًا قبل تشغيله على أجهزتهم الشخصية. فمع أنه كُتب بعناية فائقة وتدقيق من قِبله ومن قِبل زملائه في الفريق، إلا أنه يظل في النهاية "كود Ruby عشوائي يُشغّل على جهازك"، مؤكدًا كقاعدة عامة على ضرورة فحص وتفحص أي كود برمجي يُعرض على الشاشات في المؤتمرات التقنية قبل تنفيذه محليًا.
```mermaid flowchart TD accTitle: مسار تشغيل وتجربة قالب Rails المخصص لـ Ractor accDescr: يوضح الرسم البياني خطوات تشغيل القالب المخصص من الرابط وحتى خدمة الطلبات عبر Ractor.
subgraph Preparation ["إعداد التطبيق"] A["مسح رمز QR والحصول على الرابط"] --> B["مراجعة وفحص كود السكربت"] B --> C["تخطي Solid Gems وتفعيل دعم Ractor"] end
subgraph Execution ["التشغيل والمعالجة"] C --> D["تشغيل خادم الويب"] D --> E["إرسال طلبات ويب فعلية"] E --> F["معالجة وخدمة الطلب عبر Ractor الرئيسي"] end ```
[29:43](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1783s) خارطة الطريق المستقبلية ودعوة مجتمع Ruby للمساهمة
ينتقل أندرو بعد ذلك للحديث عن المرحلة القادمة وما ينتظر هذا المشروع من عمل وتطوير؛ فالهدف المستمر داخل شركة Shopify خلال العام المقبل هو مواصلة توسيع دعم Ractor في إطار عمل Rails، والعمل على جعل المنظومة البيئية المحيطة برمتها أكثر توافقًا وأمانًا، بدءًا من مكتبات Ruby الخارجية (Gems) وصولاً إلى التطبيقات الحقيقية الإنتاجية. ومع أن فريق البنية التحتية في Shopify سيقود جزءًا كبيرًا من هذا العمل، إلا أن أندرو ركّز بحماس على أن الفرصة مفتوحة ومتاحة بالكامل أمام أفراد مجتمع Ruby للمشاركة الفعالة في هذه الرحلة.
ودعا الحضور والمطورين إلى اتخاذ خطوات عملية بسيطة: إنشاء تطبيق جديد بالاعتماد على القالب المتاح، ثم إضافة وظائف وميزات برمجية جديدة إليه. وبطبيعة الحال، من المرجح جدًا أن يصطدم المطور بخطأ متعلق بعزل Ractor (Ractor isolation error) في مكان ما، وهنا تكمن الفرصة الذهبية لتجهيز المساهمة القادمة وتصحيحها في كود Rails المصدري. كما شجع أصحاب المكتبات البرمجية أو المساهمين فيها على تدقيق حزمهم لجعلها Ractor-safe، وحث أصحاب المشاريع الجانبية على استكشاف مدى أمان تطبيقاتهم الصغيرة مع Ractor. وبيّن أن الاستعانة بالبرامج والوكلاء الآليين أثبتت جدارتها في رصد هذه المشكلات وعزلها وحلها بسرعة، مما يتيح للجميع إحراز تقدم لافت.
واختتم أندرو كلمته بأمنية وتطلّع للمستقبل، معربًا عن أمله الصادق في أن يقف هو، أو أحد زملائه، أو أحد الحاضرين في القاعة، على خشبة المسرح في العام القادم لإلقاء محاضرة تستعرض التجربة الكاملة لتشغيل Ractor في بيئة الإنتاج الفعلية، واصفًا ذلك بأنه سيكون إنجازًا رائعًا بحق. ثم وجّه شكره وامتنانه الجزيلين لجميع زملائه والمتعاونين الذين ساهموا في كتابة الكود وأثروا النقاشات بآرائهم وملاحظاتهم التي حوّلت هذا المشروع إلى واقع، وشكر الحضور على استماعهم وتفاعلهم.
- **خطوات عملية للمجتمع:** - توليد تطبيق تجريبي عبر القالب البرمجي وإضافة مزايا جديدة لرصد أخطاء العزل وتقديم إصلاحات لـ Rails. - فحص حزم الـ Gems وتحديثها لتتوافق مع معايير الأمان الخاصة بـ Ractor. - تجربة تحويل المشاريع الجانبية واستخدام أدوات الأتمتة البرمجية لاكتشاف الثغرات وتصحيحها على نحو سريع. - التطلع إلى مشاركة تجارب واقعية لاستخدام Ractor داخل بيئات الإنتاج في المؤتمر القادم.
## Notable quotes > [00:10](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=10s) أرجو منكم الترحيب بي وتمنياتي لي بالتوفيق — Andrew Novoselac
> [04:06](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=246s) لا أعلم إن كنتم تتابعون الأخبار، لكن تكلفة الذاكرة أصبحت باهظة جدًا هذه الأيام — Andrew Novoselac
> [04:06](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=246s) أن خادم الويب القائم على Ractor يمكن أن يسمح لنا بزيادة التزامن في نظامنا دون زيادة الذاكرة أو زمن الاستجابة — Andrew Novoselac
> [09:22](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=562s) خطأ: لا يمكن مشاركة الإجراء self من ملف rails/initializable.rb في السطر 44 — Andrew Novoselac
> [09:22](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=562s) رأى بعض الأمور الغريبة في تطبيقات Rails، لكن نأمل ألا نُنشئ مُهيئات أثناء معالجة الطلبات — Andrew Novoselac
> [09:22](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=562s) undefined method freeze for Concurrent::Map — Andrew Novoselac
> [13:53](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=833s) لا يهتمون إلا بالمال ولا يتعبون أبدًا — Andrew Novoselac
> [19:42](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1182s) حلقة وكيل أخرى فقط، يا صديقي — Andrew Novoselac
> [19:42](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1182s) يغرقون في تعليمات الذكاء الاصطناعي البرمجية — Andrew Novoselac
> [28:15](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1695s) لذا لا تعتاد عليه — Andrew Novoselac
> [29:00](https://www.youtube.com/watch?v=MVKUx-B_wHs&t=1740s) كود Ruby عشوائي يُشغّل على جهازك — Andrew Novoselac
## Mentioned Andrew Novoselac, Shopify, Ruby on Rails, Rails World 2026, Ractors, Threads, Processes, GVL (Global VM Lock), Writebook, Basecamp, Keno, Puma, Aaron Patterson, Concurrent::Map, Solid Cache, Active Record, Action Cable, David Hamilton, Rack, Claude 3 Opus, Toronto Ractors, Action View, Action Pack, RuboCop, ractor-dispatch, Nokogiri, Cougar, Kino
## Video description Ractors let Ruby run code truly in parallel inside a single process. They combine the parallelism of processes with the shared memory of threads. So what would it take to run Rails on a Ractor-based web server? At Rails World 2026, Andrew Novoselac, a developer on Shopify's Ruby on Rails Infrastructure team, takes a look at the effort to make Rails Ractor-safe.
Andrew starts by explaining how Ractors compare to processes and threads, and why a Ractor web server is worth pursuing. He then explains why making a framework the size of Rails Ractor-safe is hard, and how his team used an AI agent loop to map the problem. He closes with the work being upstreamed to Rails today and what's coming next.
***
Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/
#RailsWorld #RubyOnRails #Ruby #Ractors #Concurrency #Performance
[Source](https://www.youtube.com/watch?v=MVKUx-B_wHs)