السلام عليكم ورحمة الله وبركاته
في سنة من السنوات وأثناء واحدة من النقاشات الجانبية مع زميل لي في العمل، ذكر لغة برمجة تدعى Elixir وأنه بصدد استخدامها في أحد مشروعاته الخارجية لما لها من مميزات
تعجبت وقتها لإني لا أرى مشكلة في عملي اليومي تستدعي الانتقال من C#/.NET إلي لغة جديدة.
لكن لا مشكلة، دعنا نلقي نظرة على هذه اللغة
ألقيت نظرة سريعة وعلمت أنها مجرد حُلة أجمل للغة أخرى وهي Erlang
وشعرت أن Elixir لغة غريبة علي مقارنة بكثير من لغات البرمجة الأخرى فلم أهتم كثيراً ومضيت
إلى أن
قادني اهتمامي المتقطع بها من فترة إلي أخرى إلي هذا الفيديو (وكان أول عهدي بالمتحدث)
Greg Young - The art of destroying software from
tretton37 on
Vimeo.
بعد مشاهدته، لمعت في عيني Erlang عموماً و Elixir خاصةً
وبدأت رحلة اهتمامي الحقيقي بالتعرف على Elixir ومعرفة المشكلة التي استدعت ابتكارها وتفاصيل عملها
ولأن Elixir هي عبارة عن لغة أجمل لل Erlang
فكل ما سيذكر لاحقاً ينطبق على Elixir & Erlang سواء بسواء
وها أنا ألخص ما وصلت إليه حتى الآن
1- قصة أريكسون مع المحولات الهاتفية
شركة أريكسون في ثمانينات القرن الماضي، كانت تعمل في انتاج معدات الاتصالات
وأحد ركائز هذه المعدات وقتها كانت "المحولات الهاتفية" phone switches التي توجه اتصالك عبر الأسلاك للوجهه الصحيحة
وكان أحد أكبر المعوقات لهم، هو احتياج هذه "المحولات الهاتفية phone switches" إلي الصيانة المستمرة
بما يشمله ذلك من مشاكل عديدة كانت تحتاج فقط إلي "إعادة تشغيل" المحول الهاتفي ليبدأ العمل بشكل سليم مرة أخرى
وكان جوهر هذه المشاكل هو الجانب البرمجي للمحولات الهاتفية -Switches Software-
مما استدعاهم إلي تكوين فريق مخصص للحل مشكلة ال Software
2- قصة Erlang
بدأ فريق العمل في تحديد ماهي الأهداف التي سيتم تصميم ال software بناء عليها، وكان هذا ملخصها
* أن يستطيع البرنامج التواصل مع برامج أخرى موزعة على أجهزة أخرى Distributed
* أن يتعامل مع الأخطاء بشكل سلس Fault Tolerant
* أن يرد بشكل شبه لحظي على ما يطلب منه Soft Realtime
* أن يعمل البرنامج بشكل متواصل Highly Available
* أن يكون قابلاً لتغيير أجزاءه بدون ايقافه بالكامل Hot Swapping
كما ترى، هذه كلها أهداف تخص "تشغيل" البرنامج،
أي أن التفكير في كيف سيعمل النظام سبق التفكير في اللغة التي سيتم كتابة هذا النظام بها
وهو ما يجعل ولادة Erlang مختلفة عن كثير من لغات البرمجة الأخرى، فكثير من اللغات الأخرى كانت خطوته الأولى هو التفكير في جوانب كتابة اللغة ثم بعد ذلك التفكير في أمثلة عملية لاستخدام اللغة
3- أول مكون من مكونات اللغة Erlang Supervisor
لو أن البرنامج الخاص بك حدث به خطأ لأي سبب من الأسباب وانهار، هل تفضل أن يتصل بك العميل ليخبرك أن البرنامج لم يعد يعمل، أم تفضل أن تكتب برنامج أخر ليراقب البرنامج الأول ليخبرك أولاً بأول إن حدث توقف؟
ماذا إن طورنا الفكرة بشكل أفضل وأصبح البرنامج الثاني (لنسمه المراقب) قادراً على إعادة تشغيل البرنامج الأول بشكل تلقائي إذا وجد أي توقف في أي وقت؟
ماذا لو كان هذا البرنامج المراقب موجود بشكل تلقائي في نظام التشغيل الذي يشغل برنامجك؟
دعوني أقدم لكم Erlang Supervisors وهذه هي وظيفته بالظبط، إعادة تشغيل برنامجك إذا توقف لأي سبب
4- ثاني مكون من مكونات اللغة Erlang Process
لو كتبت برنامج لعميل لديك، وظيفته أن يمر على كل الصور المخزنة لدى العميل، لتعديل مقاس الصور
ففي العادة، ستلجأ ل threads لمعالجة أكبر عدد من الصور دفعة واحدة واختصار الوقت
لكن ماذا لو أن thread واحدة واجهت خطأ برمجياً أدى إلي امتلاء ذاكرة البرنامج الخاص بك ثم انهياره؟
ال threads قدمت حلاً جيداً لفصل عمليات المعالجة processing operations عن بعض
لكنها لاتفصل التعامل مع الذاكرة ويمكن لكل واحدة منها القراءة والكتابة من نفس عنوان الذاكرة وهو ما قد يسبب مشاكل كثيرة
هنا تقدم ال Erlang حلها العبقري -من وجهة نظري- وهو فصل كل من عمليات المعالجة والذاكرة أيضاً
وبدلاً من اسم thread أسمت هذا الحل الجديد باسم Erlang Process
عند تشغيل أي Erlang process تكون مساحة الذاكرة المتاحة لها معزولة تماماً عن أي مساحة ذاكرة متاحة ل Erlang process أخرى، بجانب أن عمليات التشغيل processing operations الخاصة بها تكون في معزل عن غيرها أيضاً من ال Erlang process
5- كيف تتواصل ال Erlang Processes مع بعضها
بما أننا ذكرنا أن كل Erlang Process معزولة بشكل كامل عن غيرها، فماذا لو أن واحدة منهم أرادات التواصل مع أخرى؟
حلت Erlang هذه المشكلة عن طريق تصميم mailbox لكل process يتم إرسال رسائل إليه
أي أن مناولة الرسائل message passing هو الوسيلة الرئيسية للتواصل بين ال Erlang Processes وبعضها البعض
كل المطلوب هو تحديد ال Erlang process id ثم الرسالة التي يجب إرسالها، وستتولى ال Erlang الباقي
وهو ما أتاح ميزة أخرى وهو إرسال رسائل إلي Erlang process موجودة على جهاز آخر بعيد عن الجهاز الذي يعمل عليه البرنامج الحالي
أي أن ال Erlang processes يمكنها التواصل مع بعضها سواء على نفس الجهاز أم على جهاز آخر موزع في مكان مختلف
6- عودة إلي Supervision Tree
بما أن كل Erlang process معزولة بشكل كامل عن غيرها، معنى ذلك أن إنهاء عملها أو إعادة تشغيلها لن يؤثر على غيرها
وهو ما سهل بناء شجرة من ال Erlang supervisors وظيفة كل واحد منها هو مراقبة Erlang process محددة أو Erlang supervisor آخر لتتكون شجرة من البرامج الصغيرة التي تراقب بعضها بعضاً وإعادة تشغيل الجزء المحدد الذي تحدث به مشكلة بدلاً من إعادة تشغيل البرنامج بالكامل
7- أحد أهم مكونات اللغة Erlang Scheduler
يمكن التفكير في Erlang Scheduler بأنه العقل المدبر ل Erlang
فلو رجعنا إلي مثال معالجة الصور، وأنك قررت استعمال Erlang لهذا الغرض. ولنفرتض أنك خصصت عدد 100 من ال Erlang process للعمل بشكل مستمر من أجل اتمام مهمتك في أسرع وقت
وكان جهاز الحاسوب الذي يعمل عليه البرنامج الخاص بك يعمل بمعالج له 4 نوى cores وكل نواة تتيح 2 threads
أي أن هناك 8 threads فقط متاحين للعمل في نفس الوقت
هنا يأتي دور ال Scheduler فهو يسحب عدد 8 Erlang process وينفذ كل واحدة على OS Thread
وإذا انتهى مثلا 6 بنجاح فيسحب 6 غيرهم من ال Erlang processes المتاحة
وإذا كانت هناك Erlang process في انتظار بيانات من أي مصدر ولم تعد تحتاج إلي الي OS Thread
سيفرغ ال OS Thread لغيرها حتى يأتي دورها
وهكذا
أي أن دوره هو التنسيق بين عدد ال Erlang processes المطلوب تنفيذها وبين ال OS Threads الحقيقة المتاحة
وهو مصمم للاستفادة القصوى من أي processor core متاحة على جهاز الحاسوب