مدونة المُظلي

كلام عن تطوير البرمجيات والمبرمجين وما حولهما

Wednesday, August 07, 2019

Elixir ضد Go


تنويه: إذا أردت التعرف أولاً على ما هي Elixir برجاء قراءة هذا المقال أولاً


قديماً قال المتنبي "وبِضِدّها تَتَبَيّنُ الأشْياءُ" وهي جملة من الحكمة بمكان
ولتعرف أهمية هذه الحكمة، دعونا نلقي نظرة على أول قيمة من قيم شركة Netflix

أكثر ما تقيمه شركة Netflix هو قدرتك على "إصدار أحكام سليمة"
فكلما ازدادت مسؤوليتك في مشاريع تطوير البرمجيات، كلما زادت أهمية مهارة "الحكم السليم" لديك.

ولإن الحكم على الشيء فرع عن تصوره
فبالتبعية عليك أن تطور مهارة خادمة أخرى، وهي مهارة "التعرف السليم" على الأفكار والتقنيات الجديدة التي تظهر بشكل مستمر

واحدة من الحيل التي استعملها عادة حينما أكون حديث عهد بمعلومة ما، ولا أدري عنها أي شئ بعد
أن اكتبها في جوجل متبوعة ب "VS" لأرى ما يناظرها فأختصر مسافة كبيرة من البحث
وأول مرة سمعت عن Elixir فعلت مثل ما أفعل دائما وكتبت
Elixir VS

وكانت أول نتيجة للبحث تذكر Go VS Elixir

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

لذلك سأحول أن أتأخذ طريقاً مختلفاً في مقارنة Go vs Elixir بأن أبين وجه التضاد بينهم وبالتبعية المواقف المناسبة لاستعمال كل واحدة منهم (وفقاً لفهمي حتى الآن)

تنويه: ذكر المواقف المناسبة أكثر، ليس معناه أن هذا هو الموقف الوحيد وأن بقية المواقف غير مناسبة بل معناه أن هذا هو أبرز استخدام أو الأكثر تميزاً/شهرة. ليس أكثر 

فعلى بركة الله نبدأ :)

أول فرق هو ال Virtual Machine

لكي يعمل أي برنامج مبني ب Elixir فعليك أن تركب ال Erlang Virtual Machine على كل جهاز تريد تشغيل البرنامج عليه

  • أي أن Elixir مناسبة أكثر لبناء الخوادم Servers حيث التحكم بها وإعدادها يكون أسهل وتحت إدارة فريق التطوير نفسه

على الجانب الآخر Go لا تحتاج Virtual Machine ولا تحتاج أي شئ إطلاقاً لكي تعمل، فهي statically compiled أي يتم تضمين "كل" ما يلزم لتشغيلها في نفس ملف التشغيل

  • لذلك هناك أهتمام كبير من المشتغلين بقطاع ال DevOps لبناء أدوات تساعدهم في عملهم باستخدام GO مثل ال command-line tools نظرا لأهمية هذا الميزة الكبيرة. ملف واحد مطلوب هو ملف البرنامج نفسه ولا شئ آخر

ثاني فرق هو ال Runtime

تأتي Elixir بنظام تشغيل كامل التجهيز battery-included runtime لبناء أنظمة موزعة distributed systems بكل ما تحتاجه من أدوات وطرق اتصال 
  • ولهذا بناء التطبيق الخاص بك ليعمل داخل cluster  يعد عملية سهلة في Elixir بل هي مصممة من أجل ذلك
أما GO فهي تأتي بأقل نظام تشغيل ممكن minimal runtime ثم تدعك أنت تقرر ما تحتاج، حتى لا يتضخم حجم برنامجك بسبب كثير من المكتبات التي ليس لك بها حاجة
  • لهذا السبب تكون GO مناسبة لل standalone apps مثل ال REST api service وبرامج ال command-line مثلما ذكرنا من قبل


ثالث فرق هو ال Scheduler

المجدول الخاص ب Elixir يعمل ك Preemptive Scheduler  أي أنه يمكن مقاطعة Erlang process إذا حدد أنها دخلت في حالة غير صحية ليتم إنهاءها منعاً من تأثيرها على ال Erlang process الأخرى
  • لهذا السبب تكون Elixir مناسبة للبرامج التي تحتاج إلي الرد في وقت محدد حتى لو كان ذلك على حساب بعض الطلبات التي سيتم إنهاءها بسبب أي خطأ حدث بها.. مثل برامج ال video streaming التي يجب أن تتلقى صور بشكل مستمر خلال وقت محدد. وإن حدث خطأ في إحضار صورة ما، فيمكن تخطيها بشكل كامل والاستمرار في بث الصور التي تليها
المجدول الخاص ب GO يعمل ك Cooperative Scheduler أي أنه لا يمكنه الإنتقال في عمله من goroutine إلي goroutine إلا بعد سماح ال goroutine الذي يعمل حاليا بذلك، وهو في العادة يعمل بشكل أسرع من ال Preemptive Scheduler لانه ليس عليه المراقبة أو التدخل
  • من أجل ذلك، تعد GO مناسبة أكثر للبرامج التي تعتبر CPU intensive مثل برامج تشفير الملفات، لانه لا يكون مقبولاً أن يتم تخطي ملف حتى لو تم الانتظار بعض الوقت حتى تنتهي العملية

وللحديث بقية

دمتم في أمان الله


ما هي Elixir


السلام عليكم ورحمة الله وبركاته
في سنة من السنوات وأثناء واحدة من النقاشات الجانبية مع زميل لي في العمل، ذكر لغة برمجة تدعى 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 متاحة على جهاز الحاسوب


Sunday, November 27, 2016

رهوان: كيف طورنا مواقع أسرع استجابة

مقدمة:
في هذه التدوينة، أكتب عن المراحل التي مررت بها شخصياً في تطوير مواقع الويب الإخبارية اعتماداً على dot net stack خلال السنوات الماضية، وأكتب عن "رهوان" وهو ال Data Access Layer الذي نعتمد عليه حالياً، والذي  ساعدنا في تحسين وقت استجابة أحد المواقع من 250 ملي ثانية وصولاً إلى 10 ملي ثانية وفي نفس الوقت خفض الحمل على قاعدة البيانات من 800 patch request/second وصولاً إلى 150 patch request/second

الزيتونة:
في أبسط صوره، "رهوان" ليس أكثر من data caching layer تم إضافته كطبقة وسيطة بين قاعدة البيانات وبين صفحات الموقع، هدف هذه الطبقة الأساسي هو توفير ال  Data Model المطلوبة لأي صفحة ويب، الوضع المثالي -والذي يتم الوصول له في معظم الأحيان- أن تتم العملية ك direct key/value retrieve operation  بحيث تطلب أي صفحة ال Data Model الخاص بها فيأتي محمل "بكل" البيانات المطلوبة "فوراً" بدون النزول إلي قاعدة البيانات، وأي تغير يحدث في قاعدة البيانات يتم إعادة بناء ال Data Model التي تعتمد على هذه البيانات بالكامل، ويتم ذلك في background tasks  .. وهو ما سنحاول شرحه في هذه التدوينة
ملاحظة: المرحلة الأولى والثانية هي استعراض لكيفية تطور الحل، يمكنك تخطيهما إن أردت

المرحلة الأولى: كود ملخبط بطئ :)
مررت  كمعظم المطورين  على مرحلة كل الإشارات بها "خضراء" فأي فرد من الفريق يريد كتابة أي كود في أي مكان بأي طريقه، فهو موضع ترحاب طالما ستكون النتيجة كود "شغال" حيث العميل عادة في غاية التعجل لإطلاق موقعه على الانترنت، وهو ما يضغط بشدة على فريق التطوير وتتحول الأولوية إلي بناء موقع "شغال" ويتم تأجيل أي حديث عن "جودة" الكود أو "تنسيق" أفضل بين أفراد الفريق، وتكون في العادة صفحات الموقع هي المسؤولة عن جلب كل ما تحتاجه من بيانات، كمثال:


كما هو واضح، يبدو الكود في هذه المرحلة كأنه بداية جيدة لوجبة "مكرونة اسباجتي" تقنية، فليس هناك نسق واحد، بل أن مهمة جلب البيانات تقع على ال Controller نفسه، ثم يتم نقل البيانات من ال Controller إلي ال View بطريقتين مختلفتين (ViewModel and ViewBag) واثناء عرض هذه البيانات نفسها، تم استعمال Html.RenderAction  مرة وتم استعمال Html.Partial مرة

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

المرحلة الثانية: كود منظم (بعض الشئ)
بعد مواجهة مشاكل عديدة في المرحلة السابقة يقر الفريق -وأنا أيضاً- أنه ليس كل الإشارات الخضراء خير، وأن علينا وضع بعض الإشارات "الحمراء" على الطرق المؤدية للمشاكل، ويبدأ الاتفاق على خطوط عريضة موحدة Design Guidelines في تصميم وكتابة الكود
ما يلي هي  أمثلة حقيقية لبعض الإشارات الحمراء التي اتفقنا عليها في الفريق الذي أعمل معه
  • لا تستعمل ViewBag or ViewData إلا للضرورة 
  • لا تستعمل Html.RenderAction إلا للضرورة
وهذا هو مثالنا بعد اجتيازه المرحلة الثانية

في هذه المرحلة تم تحسين وضع الكود عن طريق:
  1. استعمال ال Unit Of Work pattern كوسيط بين قاعدة البيانات وبين ال Controller وهو ما يفتح الباب لعمل optimization للطريقة التي يتم جلب البيانات بها من قاعدة البيانات بدون لمس أي Controller بعد ذلك
  2. الاعتماد على ال Dependency Injection لتقديم ال Unit Of Work المطلوبة لل Controller
  3. الاعتماد على ال ViewModel كطريقة وحيدة لنقل البيانات من ال Controller ل ال View والذي من المفترض أن يساعد أي مطور في الفريق على معرفة كل البيانات المطلوبة لرسم أي View بالقاء نظرة واحدة على ال ViewModel الخاص به، ما يعني أخطاء أقل
  4. تم الاستغناء عن RenderAction فهي تتطلب إنشاء نسخة جديدة من ال Controller المستهدف وتمشي في مسار أطول وأبطئ من RenderPartial فإن لم يكن هناك سبب وجيه فال RenderPartial هي الإختيار الأول لنا
  5. استعمال OutputCache والذي سيجعل ال asp.net process تحتفظ بالنتيجة التي خرجت من ال Index Action لمدة 60 ثانية، قبل إعادة طلب النتيجة من جديد من ال Controller وهو ما يساعدنا في تحسين وقت استجابة الموقع هنا

المرحلة الثالثة: رهوان
لفهم رهوان، دعونا نجري مقابلة معه

أنا: السلام عليكم
رهوان: وعليكم السلام

أنا: ممكن تعرف الناس بك
رهوان: أنا Data Access Layer مُحَسنّ، مسؤول عن جلب البيانات لل Presentation Layer

أنا: لماذا تقول أنك "مُحَسنّ" ماذا يميزك عن أي Data Access Layer آخر
رهوان: أنا مصمم بحيث يكون انسياب البيانات غالباً في اتجاه واحد

أنا: ماذا تقصد بانسياب البيانات عندك في اتجاه واحد
رهوان: قبل الإجابة، اسمحلي أشرح المشكلة التي جئت لحلها أولاً
  • في العادة عند طلب صفحة ويب معينة، تنزل الصفحة -أو ال data access layer الخاص بها- إلي قاعدة البيانات لجلب ما تحتاجه من بيانات، ويتم ذلك بمعزل عن أي صفحة أخرى، وهو ما يتسبب في تكرار جلب نفس البيانات -التي لم تتغير في قاعدة البيانات منذ مدة- بدون داعي
  • كمثال، لو أن هناك ثلاثة أخبار كتبهم نفس الكاتب، وتم تصفح الثلاث أخبار في نفس اللحظة، سيتم جلب بيانات الكاتب من قاعدة البيانات ثلاثة مرات في نفس اللحظة أيضاً، لأن الثلاث صفحات تحتاج إليها، وهذه المشكلة هي التي استدعت منا بناء خط Data Caching جديد وراء الصفحات لحفظ البيانات المطلوبة مرة واحدة فقط ثم تقديمها لأي عدد من الصفحات

أنا: هذا عن المشكلة، فماذا عن الحل الذي جئت انت به؟
رهوان: الحل هو نقل كل البيانات الهامة أولاً بأول من قاعدة البيانات إلي ال Data Caching Engine حتى لو لم يتم طلبها بعد في موقع الويب، بذلك نضمن جاهزية دائمة للبيانات وانسياب في اتجاه واحد، من قاعدة البيانات إلي الذاكرة إلي صفحة الويب

أنا: وكيف تم تحقيق ذلك؟
رهوان: عن طريق هذا التصميم
أنا: ماذا يعني هذا المخطط/التصميم
رهوان: يوضح المكونات التي اعتمد عليها لإنجاز مهمتي وهي:
  • Change Detector: مهمته التقاط أي تغير حصل في قاعدة البيانات وإعلام ال Cached Repository بذلك
  • Cached Repository: مهمتها توفير البيانات لأي طرف يطلبها، وتحاول توفيرها من ال Cache Engine مباشرة إن استطاعت أو جلبها من ال Repository أولاً ثم وضعها في ال Cache Engine ثم توفيرها لمن طلبها
  • Cache Engine: مهمته الاحتفاظ بالبيانات في الذاكرة in-memory
  • Repository: مهمتها النزول الفعلي لقاعدة البيانات لجلب البيانات المطلوبة
أنا: ولكن أي ORM مثل Entity Framework يمكنه أن يفعل كل ما ذكرته انت، فلم كل هذا؟
رهوان: شتان بين الطريقتين، ف Entity Framework مثلاً غير مصمم ك Thread Safe أي لا يمكن لأكثر من صفحة التعامل مع نفس ال Entity Framework Context بينما رهوان مصمم ليكون نقطة تواصل واحدة مع جميع صفحات الموقع

أنا: ممكن نتصرف في موضوع ال Thread Safe بطريقة أو بأخرى، ونعتمد على ال ORM بدلاً من كل هذا التعقيد
رهوان: بهذا الشكل تكون حللت نصف الأحجية فقط، فكيف ستحل النصف الآخر؟

أنا: وما هو النصف الآخر؟
رهوان: الاستعلامات البطئية على قاعدة البيانات، فتكفي خمس دقائق متابعة ب sp who is active لتكتشف أن ال ORMs عموماً و Entity Framework على سبيل المثال يتعامل مع الاستعلامات المعقدة complex queries بشكل غير كفء، ما ينتج عنه -عند الضغط على الموقع- time out errors كثيرة، بينما فصل ال Data Cache عن طريقة جلب البيانات سيعطي لنا حرية كبيرة في جلبها من أي طريق (مثل dapper) وإعادة كتابة استعلامات محددة بشكل يدوي لزيادة كفائتها بدون التأثير على طريقة ال Caching الخاصة بها

أنا: رجوعاً إلي المخطط الذي وضحته انت منذ قليل، ممكن مثال عن كيف تعمل الأربع مكونات التي تحدثت انت عنها مع بعضها البعض
رهوان: خذ هذا المثال -الحقيقي-
  1. مشرف في موقع إخباري نشر خبر جديد
  2. تم حفظ الخبر الجديد في قاعدة البيانات
  3. التقط ال Change Detector أن هناك خبر جديد في قاعدة البيانات تم نشره ، فنادى على Cached Repository لإحضاره قبل حتى أن يطلبه أي أحد
  4. ال Cached Repository تجلب الخبر من قاعدة البيانات وتحتفظ به في ال Cache Engine
  5. أحد ال Controllers يطلب الخبر، فيتم مناولته مباشرة من ال Cache Engine
لم يتحمل ال Controller في هذه العملية أي تكلفة من تكاليف جلب الخبر من قاعدة البيانات، مما حسن جداً من وقت استجابته على متصفحي الموقع

أنا: معنى ذلك انك ستنسخ قاعدة البيانات بالكامل في ال Cache Engine الخاص بك؟
رهوان: بالطبع لا، فلدي طريقة أحدد بها البيانات التي تستحق الاحتفاظ بها في ال Cache Engine والبيانات التي ستخرج منه

أنا: إذاً هل ممكن بعض التفاصيل عن طريقتك في تحديد البيانات التي ستظل في ال Cache Engine؟
رهوان: في المواقع الإخبارية مثلاً تكون الأهمية القصوى لأخبار آخر شهر، ثم تأتي الأولوية للأخبار ذات معدل التصفح العالي، أما غير ذلك فيمكن أن يظل خارج ال Cache Engine ويتم جلبه من قاعدة البيانات عند الطلب

أنا: إذاً لن يكون انسياب البيانات في اتجاه واحد دائماً
رهوان: لذلك قلت ذكرت كلمة "غالباً" وأنا أتحدث عن هذه الميزة، فنسبة كبيرة من طلبات البيانات ستكون في اتجاه واحد، ونسبة أقل سيتم جلبها من قاعدة البيانات أولاً قبل تقديمها لمن طلبها

أنا: رجوعاً إلي المكونات الأربعة التي تحقق ما تحدثت انت عنه، هل ممكن تفاصيل عن كيف تم بناء كل مكون من هذه المكونات
رهوان: بالتأكيد، مع ملاحظة ان طريقة البناء الداخلية لكل مكون يمكن أن تختلف مع الوقت، إلا أن هذه هي التفاصيل الحالية
  • Change Detector: البناء الحالي تم عن طريق تنفيذ استعلامات دورية sql queries على قاعدة البيانات لمعرفة أي بيانات تم تحديثها وذلك باستخدام تاريخ تعديل البيان، وتم الإعتمادعلى Hangfire لجدولة وتنفيذ هذه الاستعلامات الدورية، لإنه ينفذها في Background Threads داخل موقع الويب نفسه
  • Cached Repository: وهي طبقة رقيقة مهمتها تنسيق العمل بين ال Repository وال Cache Engine لكن أهميتها أنها نقطة التواصل الوحيدة مع ال Presentation Layer 
  • Repository: وهي المكان الذي ينفذ عمليات جلب البيانات من قاعدة البيانات فعلياً، ونعتمد فيه على Dapper بصفة أساسية لسرعته الكبيرة ، ونعتمد أيضاً على Entity Framework في الاستعلامات غيرالمعقدة، وهناك ملاحظة هامة هنا:
    • أحد القوانين الحاكمة هنا هو التقليل من ال sql joins إلي أقل قدر ممكن فمثلاً عملية جلب خبر من قاعدة البيانات لن تجلب معه بيانات كاتب الخبر، بل ستكتفي بجلب رقم كاتب الخبر فقط author id ثم يتم طلب بيانات الكاتب من ال Cached Repository الخاص بالكتاب، فالاحتمال الأكبر أن بياناته موجودة بالفعل في ال Caching Engine فنكسب مرتين، مرة بتقليل ال sql joins ومرة بعدم جلب بيانات الكاتب من قاعدة البيانات بدون داعي
  • Cache Engine: تم بنائه باستخدام static ConcurrentDictionary لبساطته وقدر التحكم الذي نحصل عليه في البيانات الموجودة داخله
أنا: ماذا عن النتائج
رهوان: على مستوى ال Server Side فقد تم قياس النتائج باستخدام Mini Profiler وهذا مثال على الفرق


رهوان: وعلى مستوى قاعدة البيانات فهذا هو الفرق قبل وبعد استعمال رهوان


في الختام:
رهوان ليس الرصاصة الفضية للقضاء على مشاكل البطء لأي موقع ويب، بل أنه ولد من رحم مشكلات المواقع الإخبارية، أما المواقع/التطبيقات التي تعمل بشكل مختلف، ستحتاج حل مناسب أكثر لاحتياجاتها، قد يكون رهوان أو تعديل له أو حتى غيره

تحدثت في هذا المقال عن "فكرة" رهوان، ولم أتطرق لرحلة تنفيذ رهوان نفسها، فقد كانت مليئة بالتفاصيل، أكثر من أن يتحملها مقال واحد، سواء في تفاصيل ال Implementation ، أو في تفاصيل المشاكل التي واجهتنا أثناء التطوير مثل Memory Leaks و Sudden Process Termination  لنكتشف بعد رحلة تشخيص عميقة أنه Unhandled Stackoverflow Exception، إن يسر الله لي، يمكن أن أكتب جزءً آخر من المقال يتحدث بشئ من التفصيل والأمثلة عن كيف نفذنا الفكرة نفسها وكيف صنعت التفاصيل الصغيرة الفارق

وهناك أيضاً تفاصيل في كيفية تطويره مستقبلاً فعلى سبيل المثال نخطط لإعادة بناء ال Change Detector ليعتمد على  Publish/Subscribe pattern بدل الاستعلامات الدورية على قاعدة البيانات مباشرة، ونحتاج تجربة ال Caching Engine إذا تم تشغيله ب Redis فماذا سيكون الفارق

إلا أني حاولت قدر الإمكان الإلمام بالصورة الكاملة مع أهم تفاصيل الحل
أسأل الله أن يكون مقالاً نافعاً

في انتظار تعليقاتكم على الحل واقتراحتكم
والحمد لله رب العالمين

Monday, May 16, 2016

Flux: الإتجاه إجباري

الزيتونه :)
خلاصة ما فهمته حتى الآن هو أن مطوري فيسبوك يرون أن التطبيقات المبنية بنظام MVC ستصبح أكثر تعقيداً وتكويناً للأخطاء غير المتوقعة مع الوقت
وجذر المشكلة من وجهة نظرهم يرجع إلي ال Model وخاصة إمكانية التعديل فيه من أي اتجاه، لذلك قرروا أن يكون انسياب البيانات في التطبيق بالكامل ذا اتجاه واحد إجباري وأن يتم تحويل ال Model إلي Read-Only Model مع إضافة بعض الإمكانيات عليه، وتم إعاده تسمية ال Model إلي Store، إذا أردت أن تعرف لماذا أخذوا هذا القرار وكيف سيتم تعديل ال Read-Only Model فتابع القراءة :)




البداية من Angular2

بعد إصدار Angular2 beta-0 تحمست له كثيراً فقد كنت متابع لأخباره ومعجب بما وصل إليه، وكنا على وشك إعادة بناء إحدى التطبيقات داخل الشركة من جديد، بهدف تقديم أداء وتجربة أفضل لمستخدميه، بعد مناقشات داخل الفريق اتفقنا على الاعتماد على Angular2 وهو -حتى الآن- قرار نراه موفق وسعداء بما حصلنا عليه من تحسن في تجربة تطوير تطبيقات ال JavaScript وجودة الكود نفسه

اثناء التجهيز لإعادة بناء أحد أجزاء التطبيق والذي نعلم انه يحتاج إلي أداء استثنائي، أردنا التعرف على ما يمكن ل Angular2 أن يقدمه لنا، وهو ما وصل بنا إلي شاطئ  Angular2 "OnPush" Change Detection Strategy والذي بدوره ساقنا إلي القراءة أكثر عن الفرق بين تعامل Angular2 مع البيانات القابلة للتعديل والبيانات الصماء Mutable data & Immutable data

ثم جاء الدور للتعرف على React & Flux وما الذي يمكنهما تقديمه لتحسين الأداء بشكل استثنائي -كما يسوق React لنفسه- وعلى الرغم اني دخلت في الأصل للتعمق في React وبحث إمكانية استعماله جنباً إلي جنب مع Angular2 إلا أن الحديث عن Flux والمشكلة التي استدعت ابتكاره كان شيقاً جداً لي،  وبعد جولة في المقالات والفيديوهات أحببت تلخيص مع وصلت إليه حتى الآن


1- ما هي المشكلة التي استدعت ابتكار Flux ؟

قبل Flux كانت معظم إطارات العمل (MVC Frameworks) المشهورة، ك Angular, Ember وغيرها، تتنافس من أجل تقديم دعم أفضل للربط التلقائي بين ما يحدث في عالم الكود (Controller) وبين ما يحدث في عالم الواجهة الرسومية (View) وذلك عن طريق توسيط البيانات (Model) بين العالمين وأي تغير في البيانات من ناحية يصل إلي الناحية الأخرى تلقائياً وهو ما يعرف ب Two way data binding

وأصبح من الطبيعي أن تجد أن تعديل صغير في ال Model ينتج عنه عدة تحديثات في أكثر من منطقة في ال View، وعلى فائدة هذه الميزة في الشاشات غير المعقدة، ستجد ان نفس الميزة أصبحت عبء على المطور في الشاشات المعقدة، وستجده يشد شعره متسائلا عن سبب بطئ التطبيق قبل أن يكتشف أن تغيير لون خبر واحد تسبب في إعادة رسم قائمة الأخبار بالكامل والذي بدوره تواصل مع ال server للحصول على بيانات محدثة عن كل خبر، فيبدأ زميلنا المطور بمعالجة الأمر قبل أن يتكرر مرة هنا ومرة هناك ويظل في حالة معالجة دائمة لآثار ال Two way data binding

المشكلة هي نفس مشكلة "الفوضى المرورية" التي تواجهها كل مدن العالم،  تخيل مثلا طريق صلاح سالم في مصر -أعاذك الله من وقفته:)- بدون جزيرة في النصف ويمكن لأي سيارة السير في أي اتجاه والدخول والخروج من أي مخرج يمينا أو يسارا، تخيلت؟ احمد الله أن الوضع ليس كذلك :)

صياغتي للمشكلة التي جاء Flux لحلها هي:
مشاركة وتعديل نفس البيانات بين أكثر من منطقة/مكون 
 State sharing & management between multiple view-parts/components


2- ما هو الحل الذي جاء به Flux ؟
هو إلغاء فكرة ال Two way data binding وأصبح هناك إتجاه واحد إجباري للتواصل بين مكونات التطبيق وبعضها البعض، مما استدعى إعادة تنظيم المكونات نفسها لتعمل بسلاسة مع فكرة الإتجاه الواحد الإجباري، ومن أجل ذلك تم تصميم أربع مكونات جوهرية، تساعدها أخرى، لكنها تظل أهم أربع مكون لا يمكن أن يطلق على التطبيق انه متوافق مع Flux بدونها

  • Store هو الأسم الجديد لل Model سابقاً وأصبح للقراءة فقط، وظيفته الوحيدة هي إستقبال بلاغات من ال Dispatcher المركزي بأن إجراء ما، يتم في التطبيق، وهو داخلياً -ال Store- يقرر إذا كان يحتاج إلي تحديث بياناته -بنفسه- أم لا، ويرمي Event إن احتاج بأنه حدث بياناته الداخلية، يمكن أن يكون هناك أكثر من Store في التطبيق الواحد
  • Dispatcher وظيفته الوحيدة توصيل أي إجراء (Action) يتم تنفيذه  في التطبيق إلي جميع ال Stores، لا يكون في التطبيق إلا Dispatcher واحد فقط
  • Action هو كائن (Object) يحتوي على وصف لإجراء ما، يتم داخل التطبيق ويحتوي على كل ما يلزم من بيانات لاتمام هذا الإجراء 
  •  View يتابع أي تغير حصل في ال Store ويعيد رسم نفسه -إن احتاج- بناء على ذلك، ويبلغ ما يحدث بداخله عن طريق رمي Events
هناك مكونات أخرى مكملة يكاد لا يستغني عنها أي تطبيق Flux، وهي:
  • View-Controller وظيفته الاستماع إلي أي Events يتم رميها من ال View وبناء ال Action المطلوب وترحيله إلي ال Dispatcher المركزي
  • Action-Creator وظيفته بناء ال Action فعلياً وفعل ما يلزم قبل وبعد بناء ال Action، عادة ما يعتمد ال ViewController عليه لبناء أي Action مطلوب


3- مثال
لو تصورنا أن هناك شاشة تعرض قائمة بالأخبار الحالية في موقع ما، ومطلوب عند الضغط على أي خبر، أن يتم تغيير لون خلفية الصف الخاص به إلي اللون الأحمر، إذا أردنا فعل هذا وفقاً ل Flux فسيكون هذا مثال مبسط جداً للكود
ملاحظة: إذا أردت رؤية الكود وهو يعمل يمكنك تجربته من هذه الوصلة https://embed.plnkr.co/B43YS3


Monday, October 12, 2015

تجربتي مع يوسي ماس UC MAS


إن كنت مشغولاً جداً توجه إلي آخر المقال "الملخص" لكني أنصح بشدة قراءة التجربة كاملة

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


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

وصلنا لأحد مراكز التدريب على اليوسي ماس في مصر، وله فروع كثيرة خاصة في القاهرة، وسألناهم عن نظام التدريب الخاص بهم، فكان عبارة عن حصة أسبوعية حوالي ساعة ونصف، غالباً تكون يوم الجمعة أو يوم السبت، أي أن الشهر الواحد يكفي أربع حصص، اجتياز المستوى الواحد يحتاج إلي 12 حصة أي ثلاثة أشهر من الانتظام، إتمام البرنامج بالكامل يحتاج من سنتين إلي ثلاث سنوات، متوسط التكلفة الشهرية هي 250 جنيها

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

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


ثانياً ملاحظات على المنهج وتجربتي:
  • لو أتم ابننا كامل البرنامج التدريبي بنجاح يمكنه حل المسائل "الحسابية" بسرعة كبيرة جداً، لكنها لن تفيده في حل المسائل "الكلامية" التي تعتمد على استنتاج وبناء العلاقة بين الأرقام

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

  • ثاني نقطة هي أيضاً "الضغط" لكن على أولياء الأمور، فمتابعة المستجدات ودعم الأولاد في التدريب عليها ثم متابعة الوقت المطلوب لإنهاء 20 مسألة (أي صفحة من المسائل) هي عملية أخرى من الضغط على ولي الأمر نفسه

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

  • مع الوقت، أصبحت كلمة يوسي ماس هي كلمة ثقيلة جداً على ابننا وعلى بنت اختي، فالانطباع الذي ترسخ عندهم حتى الآن، انها صعبة عليهم، وهو ما أخشى -إن استمر- أن يتحول لقناعة سلبية ضد الرياضيات عموماً



ثالثاً مقارنة رياضيات يوسي ماس مع رياضيات المونتيسوري (من سن 3 سنوات إلي 6 سنوات):
  • من وجهة نظرنا، أهم نقطة في رياضيات مونتيسوري انها قائمة على الانشطة التعليمية، والتدرج المنظم فحتى لو لم يحصلّ الطفل المادة العلمية، فانطباعه عن الرياضيات سيكون إيجابي، حيث ارتبطت دائماً باللعب والانشطة

  • في العادة، لا يفهم الطفل ماذا تعني 4x5 يمكنه أن يقول لك انها تساوي 20 لكن لا يستطيع أن يعرف "لماذا؟" لماذا 4x5 تساوي 20 وماذا تعني أصلاً كلمة (ضرب) في الرياضيات .. لا تجاوب اليوسي ماس على هذا السؤال ، بينما تقدم المونتيسري إجابة منطقية للطفل .. فهو يستطيع أن يرى العلاقة بين 4 صفوف وخمس أعمدة بنفسه ويلمسها بيديه

  • اليوسي ماس لم ينجح من وجهة نظرنا في بناء العلاقة بين الأرقام في ذهن الطفل، فكل الأرقام هي حلقة في العداد، وتكون قيمتها 1 أو 10 بناء على مكانها في العداد، بينما في رياضيات مونتيسوري الواحد هو خرزة واحدة بينما العدد 10 هو صف من عشر خرزات مربوط في بعضه، مما يمكن الطفل من بناء العلاقة بين الأرقام مع الوقت



رابعاً مقارنة رياضيات يوسي ماس مع رياضيات سنغافورة (من سن 6 إلي أعلى)

توضيح: رياضيات سنغافورة ليس لها علاقة بأي طريقة من طرق الحساب الذهني (لا يوسي ماس ولا IMA ولا أمثلتهما) ويمكن أن أفرد تدوينة لشرح ما هي رياضيات سنغافورة قريباً لكثرة السؤال عنها
خذ هذه المسألة الكلامية: اشترى عمر 4 علب زبادي أكثر من أمل، فإذا علمت أن أمل اشترت 12 علبة زبادي .. احسب كم علبة زبادي اشتروها جميعاً
رياضيات سنغافورة تدرب الطفل على 7 خطوات مرتبة لحل أي مسألة كلامية
  1. اقرأ المسألة جيداً
  2. استخرج المتغيرات
  3. ارسم شريط الأعداد
  4. قسم المشكلة وظبط شريط الأعداد
  5. ضع علامة الاستفاهم
  6. نفذ العملية الحسابية
  7. اكتب الإجابة بصيغة كلامية


لمشاهدة فيديو شرح المسألة:

خطوة 6 في رياضيات سنغافورة ستصل إلي هذه العملية الحسابية 12+16 ، ستوجه الطالب إلي تقسيم العملية إلي التالي 10+10+6+2 وستكون النتيجة 28

بينما طريقة يوسي ماس لم تستطيع أن تقدم طريقة منظمة لحل المسألة الكلامية وإن وصل الطالب إلي العملية الحاسبية 16+12 سينفذها في ذهنه بسرعة جداً وهي ميزه طبعاً


لكني أفضل أن يتعلم الطفل تجزئة المشكلة وتبسيطها كما حدث مع رياضيات سنغافورة، فرأيي أنه حتى في هذه المرحلة تفوقت رياضيات سنغاورة على يوسي ماس أيضاً


الملخص:
قررنا التوقف عن الاستمرار في برنامج اليوسي ماس، لما لمسناه من ضغط كبير يمارس على  ابننا وانطباع سلبي بدأ يترسخ عنده تجاه الرياضيات، ولأن البرنامج قائم على الحاجة إلي التدريب المستمر أكثر من الحاجة لفهم سلس وعميق للرياضيات
حيث تعلمنا أن سرعة الحساب ليست هي الفيصل، بل بناء العلاقات بين الأرقام وسهول استنتاج روابط جديدة هي ما تميز بين التعليم العادي والتعليم الجيد

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

Saturday, November 20, 2010

تشيلي الواحة الفتـيّة لرواد الأعمال التقنية

أنشر هذه المقالة المترجمة للعربية بعد إعلان الأخ عماد المسعودي فوز هذه المقالة ضمن مسابقة ترجم للريادة، سعدت بهذه المسابقة سعادة خاصة، وذلك لانها تهتم بنشر ثقافة ريادة الأعمال والتي نفتقدها بشدة في مجتمعاتنا وتشجع المحتوى العربي التقني على الانترنت، وسعد بالجائزة لأنها أول 200 دولار يدرها علي حبي للغة العربية :) والآن أترككم مع المقالة

 

هذه المقالة مترجمة عن فيفيك وادهاوا، رائد أعمال حالياً وأكاديمي سابق، محاضر غير متفرع في جامعة كاليفورنيا في بيركلي، باحث محترف في كلية الحقوق بجامعة هارفارد وإداري مقيم في جامعة ديوك

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

رجعت لتوي من رحلة رائعة إلي شيلي، حيث كنت مدعواً من قبل حكومتها لإلقاء نظرة على على ما حققوه من إنجاز في التحول إلي مركز تعهيد خارجي. ذهلت حقاً من قدرتهم على النمو بدأً من لا شئ وصولاً إلي مليار دولار من العائدات خلال سبع سنوات أو يزيد.  وتعجبت كيف لهم أن يحققوا مثل هذا الإنجاز في مجال متعطش للكفاءات مثل التعهيد الخارجي بدون خنق الصناعات المحلية بامتصاص المهندسين والعلماء الأكفّاء إلي وظائف ذات رواتب مغرية. أخبرتهم بأن أمامهم فرصة سانحة لمنافسة الهند في مجال التعهيد الخارجي كمثل التي للهند في منافستهم في تصدير النحاس. الهند شعبها تخطى المليار. بينما شيلي 16 مليون نسمة، أقل من تعداد بعض المدن الهندية. لكن شيلي تستحوذ على 40% من احتياطي النحاس العالمي، فرق هائل حقاً.

250px-South_America_location_CHIشيلي يمكن ألا تكون الحصان الأسود في التعهيد الخارجي. لكنها يمكن أن تكون درّة أمريكا الجنوبية بقدرتها على التحول إلي الواحة الجديدة للمهاجرين بشكل عام ورواد الأعمال التقنية الذي يشكل التصدير محور أعمالهم. وضعت الحكومة الشيلية تشكيلة من الحوافز الخرافية للشركات التي تشكل التقنية عمودها الفقري والتي تصدر منتجاتها. الحكومة تريدك أن تستثمر 500,000 دولار خلال خمس سنوات لكنها مرنة جداً في آلية تحقيقك لذلك.

ماذا بعد استثمارك 500,000 دولار، ما الذي ستحصل عليه بالمقابل؟ كبداية، سيمنحوك تأشيرة دخول. يمكنك البقاء كيفما يحلو لك – حتى بشكل دائم. عليك أن تقدم خطة عمل لكنك تتمتع بحرية كبيرة في الاختيار من باقة الأعمال التي يدعمونها. أي عمل يقدم منتجات عالية التقنية، منتجات طبية، منتجات تكنولوجيا حيوية، منتجات تكنولوجيا خضراء غير مضرة تحصل على ختم الموافقة، وكذلك صناعات تطوير البرمجيات أو حتى تطوير ألعاب الويب أو تطوير شبكات التواصل الاجتماعية. حتى لو كنت ستنشأ مركز اتصالات أو مركز دعم فني يبيع خدماته للشركات الأجنبية ويظنون أنك مؤهل، ستحصل على التأشيرة.

لكن قبل ذلك، تريد التحري عن البلد أليس كذلك؟ ستمنحك الحكومة 60% من تكاليف التحري أو ما قد يصل إلي 30,000 دولار لزيارة واستكشاف شيلي. وسيضمنون لك 30,000 دولار أخرى لبدء شركتك في شيلي. إن قررت العمل داخل أحد المراكز التقنية الخاصة بهم، ستتكفل الحكومة بدفع الإيجار لمدة خمس سنوات (قد يصل إلي مليون دولار) نيابة عنك أو ستقتسم معك التكاليف إن أردت أن تستقر في أي مكان آخر في هذا البلد الرائع.

ماذا عن حوافز القوى العاملة؟ شيلي قد أمّنت ظهرك بالفعل. فستدفع الحكومة لك (كرائد أعمال تم قبوله) ما قد يصل إلي 25,000 دولار للسنة الأولى "كمصاريف تدريب" لأي مواطن شيلي تعيّنه. بالمناسبة شيلي تملك بعض مدارس الهندسة المتميزة لذا فانتقاء مبرمج جافا أو C# لن يكون عملاً شاقاً، الواحد منهم يتقاضى من 15,000 إلي 30,000 دولار في السنة، أمازلت لا تجد أي مواطن موهوب؟ ستدعم شيلي مجهوداتك لاستقدام من تريد من سانيفيل في مومباي أو من أي مكان قد تجدهم فيه. ويمكنك تدريب هؤلاء الناس على حساب شيلي أيضاً. وإن قررت شراء بعض الأراضي وبناء معاملك أو مكاتبك الخاصة، سيدفعون لك 40% من تكاليفك حتى 2 مليون دولار. ماذا عن المهاجرين المؤقتين أو الموهوبون الذين يرغبون في الانتقال إلي شيلي؟ بسيطة. وفر وظيفة تقنية مناسبة وستحصل على التأشيرات، بدون طرح أي أسئلة. هل بدأت تشعر بما أشعر به؟ (ملاحظة: إن حصلت شيلي على ربع المهاجرون المؤقتون العاملون بوظائف تقنية في أمريكا الآن، فستكون قريبة من مضاعفة القوى العاملة في التقنية داخلها)

لكن مهلاً، مؤكد الموضوع فيه إنّ. بحثت عن تلك الإنّ لكني لم أجدها قط، حتى أني زرت فينا ديل مار وهو منتجع خلاب يبعد ساعة عن سانتياغو. الطقس والمناظر الطبيعة تذكرك بكاليفورنيا (باستثناء أن فصول شيلي المناخية معكوسة – عندما يحل الصيف في الولايات المتحدة، يكون الشتاء مستقراً في الجنوب) يضم منتجع فينا ديل مار شواطئ رائعة ويبدو كأنه النسخة الحديثة من ميامي، وتخيل كم تكلف شقة غرفتين مفروشة بالكامل ومواجهة للشاطئ؟ 500 دولار في الشهر. حتى عاصمتها سانتياغو بمجرد أن تطئها قدمك تشعر كما لو أنك في أحد البلاد الأوروبية الحديثة لكن بمعدل جرائم منخفض للغاية، طقس رائع، مواطنين ودودين. فضلاً عن ركوب الأمواج الرائع في شيلي

ويعلو كل هذا، شيلي دولة ديمقراطية مزدهرة وواحدة من أكثر الاقتصادات انفتاحا في أمريكا الجنوبية. في الحقيقة، لو عزمت على إنشاء شركة ولم يكن هناك حاجة للتواجد في مكان بعينه، سأبدأها في شيلي بدون تردد. ما أدهشنى حقاً هو أن العديد من الشيليين الذين اللتقيت بهم يفاخرون بأن بلادهم أصبحت "أرض المهاجرين". الكل يحكي قصص عن كيف قامت شيلي على أكتاف المهاجرين وكيف رحبت بالمهرة المهضموي الحقوق. هذا يذكرني كيف كانت أمريكا قبل أن تبدأ حركات مناهضة الأجانب بإلقاء اللوم على المهاجرين لأنهم مصدر كل تقصير وسبب كل بؤس. يبدو هذا أكثر من معقول ليكون صحيحا، أليس كذلك؟ هناك بعض الجوانب السلبية. شيلي تبعد 15 ساعة عن الساحل الغربي. وإن أردت البقاء فترة طويلة، ستحتاج لتعلم الاسبانية. هذا ليس ثمناً  كبيراً مقابل كل تلك المميزات.

أتتوق لتتحرر من التكاليف والقيود التي تفرضها طبيعة التكنولوجيا في أمريكا الشمالية؟ عليك بالجنوب أيها الفتى التقنيّ

Saturday, July 10, 2010

مرحلة المراهقة البرمجية – التمرد على المشاريع

هل خطر في بالك مرة أسئلة من هذه النوعية :

- سئمت هذا المشروع وهذا العميل

- المبرمجون في الخارج يبرمجون بطريقة متقدمة عنا بسنين ضوئية

- أنا مبرمج غير كفء

هذه الأسئلة يمكن أن تدور بخلد كثيراً منّا وقليل من يتحدث بها طلباً للنصيحة، بل كثيرا من هذه الاسئلة وأخواتها افسدت عليه الاستمتاع بسنوات عمره الماضية

مررت شخصياً بهذه المرحلة، وهي مرحلة المراهقة البرمجية كما أسميها

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

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

فكل المشاريع التي اعمل فيها تبدأ ولا أراها تنتهي أبداً

وكل مشروع أعمل فيه هو متأخر تكنولوجياً عن أحدث ما نزل من تكنولوجيا تطوير البرمجيات

وكل مشروع أعمل فيه تكثر في التعديلات لدرجة أرهقت شيفرة المصدر فأصبحت مهلهلة، ولا استطيع النظر إليها وأفتخر أنها من صنع يدي

وكنت سأظل في هذه المرحلة لو أن من الله علي بحضور جلسة من جلسات التعريف بال Agile Development  أو البرمجة المرنة

ولشرح فوائد البرمجة المرنة  Agile Development  بدأ المحاضر بشرح المشاكل التي استدعت اللجوء إليها

ولأول مرة في تاريخي رأيت مشاكلي التي أعاصرها في مشاريعي يوم بيوم يشرحها فرد آخر أمامي بنقاط واضحة

بل الأهم من ذلك أني شعرت أني لست وحدي في صحراء مشاكل تطوير البرمجيات

وزادت قناعتي بأني لست وحدي عندما بدأت متابعة اللقاءات المسموعة على الانترنت Podcasts  والتي يتحدث فيها المطورون الأجانب عن متاعبهم في تطوير البرمجيات

وبعد فترة من الزمن بدأت انتقل لمرحلة أخرى في اثناء عملي في أي مشروع

وهي مرحلة قبول التحدي كما أسميتها

وأول شئ بدأت بتصححيه في هذه المرحلة هو فهمي لمشاكل المشاريع، فلم أعد أطلق عليها مشاكل بل استبدلتها بتحديات

وثاني شئ مميز حدث لي في هذه المرحلة هو بدء مصالحة مع نفسي بأن أرضى بوجود هذه التحديات، لانه لولا وجودها لما احتاجت الشركات لمثلي ولا تمايز المتميزون في إيجاد حلول مبدعة لتخطي هذة التحديات

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

ال .NET Framework عود على بدء

ال .NET Framework هي المحطة الأولى التي ينطلق منها أي مطور تطبيقات دوت نت لذلك فهو من أكثر الموضوعات التي يتم الاستفاضة في شرحها ألا أنه بطبيعة الحال فإن غالبية من يشرح لهم ال .NET Framework يكونوا من المبتدئين فبالتالي يحتاج فهم ال .NET Framework عندهم إلي وقت وممارسة فالصورة عندهم غير مكتملة وهناك بعض المعاني التي يحفظونها كما هي إلي أن يشاء الله ويفهمون هذه المعاني فهماً عميقاً وتضح عندهم الصورة، ولأني لست استثناء من هذه القاعدة أكتب هذا المقال بعد أن شاء الله وفهمت كثيراً من المعاني التي كان أقصى صدى لها في بداية تعلمي إياها هو نطقها فقط لذا كان من الأهمية بمكان كتابة مثل هذا المقال والمقسم كالآتي :
· الحياة قبل ال .NET Framework
· الحياة بعد ال .NET Framework
1- الحياة قبل ال .NET Framework
في هذه الأزمان كان على المبرمج أن يكون من نوعية – الكل في واحد - وأن يؤدي بمهارة أربعة أدوار وهي

  • البنّاء
  • المؤرخ
  • النصوح
  • المفتش
  • وهي بالطبع بجانب دوره كمبرمج ، ودعنا نفصل كل دور من الأربعة السابقة

    1- يحتاج المبرمج أيامها أن يكون بنّاء لأنه سيبني بنفسه طريقة لإدارة الذاكرة وأخرى لإدارة الأخطاء بالإضافة لبناء كل سطر كود سيحتاجه البرنامج فلو قررت مثلاً بناء لعبة فعليك أن تبني نظام يتأكد من أن الذاكرة ليس فيها كائنات Objects غير مستعملة ونظام آخر لإدارة الأخطاء التي يمكن أن تنتج من اللعبة بالإضافة إلي بنائك لمحرك اللعبة ونظام الرسم على الشاشة وغير ذلك من مهام .

    2- ولن يستقيم دوره كبناء بدون أن يكون مفتش جيد يعرف كيف يفتش عن خصائص نظام التشغيل الذي سيعمل عليه ونظام بناء نظام التشغيل فمثلاً إن كان 32-bitأم 64-bit وإن كان البرنامج سيعمل على أكثر من نظام تشغيل فيجب عليه أن يحيط علماً بكل الفروقات بين نظم التشغيل المختلفة فما يمكن عمله في Windows ME لا يمكن عمله في Windows NT فأبسط شئ يمكن ذكره هو عبارة عن اسماء مكتبات النظام System DLL التي يمكن ان يتغير اسمها من نظام تشغيل إلي نظام تشغيل آخر فبالتالي عليك أن تكون ملم بكل أسم لكل نظام تشغيل

    3- يجب عليه دائما أن يكون ناصحا لزملائه بإتباع أساليب قياسية لتنفيذ برامجهم حتى يتسنى له التكامل مع برامجهم فاختلاف لغات البرمجة واختلاف طريقة بناء البرامج سببت مشكلة وهي عدم وجود اسلوب قياسي تستطيع من خلاله البرامج أن تتكامل مع بعضها البعض والأسلوب الأكثر شهرة هو ما يعرف بال COM (Component Object Model)

    4- أخيراً لزاماً عليه أن يكون مؤرخاً لكل إصدارة من برنامجه ومكتبات النظام System DLL التي استعملها وتواريخ إصدار هذه المكتبات DLL حتى يمكنه نسخها إلي كل نظام تشغيل سيعمل عليه لأنه ياويل برنامجه إن بدل أحد المبرمجين غيره ملف من ملفات مكتبات النظام System DLL بملف آخر مختلف في تاريخ إصداره عن تاريخ إصدار ملف صاحبنا – هذه العملية عرفت بجحيم المكتبات DLL Hell -

    أي أن ملخص هذا الكلام في أنه كان هناك عبء كبير ملقى على عاتق أي مبرمج نظراً لتوليه إنجاز كل هذه الأمور وأكثر بنفسه
    - الحياة بعد ال .NET Framework
    جاء ال .NET Framework حاملاً هدايا إلي ثلاث
    1- إلي المبرمج فصدق أو لا تصدق فقد حمل عن كاهل المبرمج الأدوار الأربع هل تذكرهم أنهم:
        · البناء : فقد أعتمد ال .NET Framework في إراحة المبرمج من هذا الدور على مكونين أساسين

    أ - نظام جديد لإدارة الذاكرة هو ال CRL (Common Language Runtime) وليس هذا فقط فقد تعدى هذه المرحلة إلي مرحلة أكبر وهي إدارة التشغيل بالكامل أي أنه منذ بداية تشغيل برنامجك وحتى إغلاقه فقد تولى ال CLR جميع مهام التشغيل من إدارة للذاكرة وإدارة للأخطاء وترجمة إلي لغة الآلة وغير ذلك.

    ب - مكتبة جاهزة فيها تقريباً كل ما يحتاجه المبرمج لإنجاز مهامه وهي تعرف باسم FCL (Framework Class Library) أو BCL (Base Class Library) كلاهما صحيح ففي هذه المكتبة بنت مايكروسوفت فئات Classes جاهزة للاستعمال تتولى هي تنفيذ المهام التي كان على المبرمج أن يبنها بنفسه سابقاً مثل إدارة الاتصال مع قاعدة البيانات والرسم على الشاشة وغير ذلك من المهام

    · أما عن دور المفتش فلم يعد له حاجة بعد ظهور أداة جديدة داخل ال CLR وهي ال JIT Compiler (Just In Time Compiler) ،

    ودعنا نستوضح قليلاً دور المفتش هذا فقد كان ذا أهمية كبيرة سابقاً لأنه كان لزاماً علي أن أخرج البرنامج من تحت يدي وهو جاهز للتشغيل المباشر على أي نظام تشغيل يدعمه البرنامج أي أن ترجمة البرنامج من لغة البرمجة التي أعمل بها إلي لغة الآلة Machine Language تتم على جهاز المبرمج ثم توزع هذه النسخة المترجمة إلي لغة الآلة على الأجهزة المستهدف لتعمل عليه

    ا أما بعد ال .NET Framework فقد اختلف الأمر حيث مازال يتم ترجمة البرنامج من لغة البرمجة إلي لغة أخرى على جهاز المبرمج ولكن هذه المرة لا يُترجم إلي لغة الآلة بل إلي لغة جديدة وهي ال MSIL(Microsoft Intermediate Language)

    وهي لغة وسيطة يمكن لأي لغة برمجة تدعم ال .NET Framework أن يتم ترجمتها إلي MSIL ثم يتم توزيع البرنامج بعد ترجمته إلي MSIL لكن ال MSIL هي لغة لا يمكن تشغيلها بشكل مباشر على الحواسيب لذا يأتي دور ال JIT Compiler حيث يستطيع أن يترجم أي برنامج مكتوب بال MSIL إلي ال Machine Language

    وفي هذه النقطة سؤال وهو طالما سيتم التحويل في النهاية إلي Machine Language فلماذا لم يتم هذا على جهاز المبرمج والأجابة هي "لرفع حمل دور المفتش" لأن من روائع ال JIT Compiler أن الترجمة التي تخرج منه بلغة ال Machine Language هي ترجمة تناسب نظام التشغيل الذي يعمل عليه ال JIT Compiler

    أي أني لو بنيت برنامج وترجمته إلي MSIL ووزعته على ثلاثة من أصحابي أحدهم يشغل Windows XP والآخر Millennium ً Windows والثالث Windows Server 2003 وكل واحد منهم قد ركب .NET Framework على جهازه فإن ال JIT Compiler سيترجم لكل واحد منهم Machine Language تناسبه وبالتالي لن أحمل هم الإصدارات المختلفة من نظام التشغيل بعد الآن -

    أما عن دور النصوح

    فلن يعود صديقنا المبرمج بعد الآن إلي حمل هم نصح أصدقائه فقد جمعهم ال .NET Framework على منصة واحدة لها نفس المقاييس ويعود الفضل في توحيد أسلوب العمل بين كل المبرمجين الذين يبنون تطبيقاتهم باستخدام

    ال .NET Framework إلي أن ال .NET Framework يخضع لمعايير تسمى

    ال(Common Language Infrastructure) CLI وهذه المعايير وضعتها مايكروسوفت بنفسها وتم نشرها على www.ecma-international.org بحيث يجب على أي طرف يريد تطوير لغة تدعم الدوت نت أن يتبعها حيث لم تضيق مايكروسوفت نطاق تطوير لغات تدعم بيئية الدوت نت عليها وحدها بل فتحته لأي طرف يريد تطوير لغة يمكنها العمل على .NET Framework وبعد أن وضعت مايكروسوفت هذه الاشتراطات بدأت هي نفسها بتباعها لتبني أول نظام إدارة تشغيل متوافق مع معايير ال CLI وهو نظام إدارة التشغيل الذي يعرف باسم ال CLR ومن ضمن المعايير التي وضعها ال CLI معيار اسمه ال CLS (Common Type System) يخدم في المقام الأول معيار بناء لغة برمجة يمكن أن تعمل على .NET Framework وعكفت مايكروسوفت على بناء أول لغة يمكن أن تعمل على .NET Framework ومتوافقة مع معيار ال CLS وكانت C#.NET ثم اتبعتها مايكروسوفت بشقيقتها ال VB.NET وهما الاثنتين يمكن ترجمتها إلي MSIL

    · ودور صديقنا المبرمج كمؤرخ

    لم يعد يحتاجه بعد أن ظهر مكون من أهم مكونات ال .NET Framework تحدثنا عنه سابقا وهو ال (Base Class Library) BCL فكل ما ستحتاجه بعد الآن أن يستعمل الفئة Class التي تناسب عمله وعند توزيع البرنامج على أي عميل سيجد نفس الفئة Class موجوده على ال .NET Framework المركب عن العميل.

    · كانت هذه الهدايا التي حملها ال .NET Framework إلي المبرمج فماذا في جعبته أيضاً

    2- هدايا إلي أي مستخدم عادي لبرنامج تم بناءه بأي لغة تعمل على .NET Framework وهي كالتالي :

    · ضمان مستوى أمنى محترم فالبرامج سابقاً كان مسموحاً لها أن تدير ذاكر الحاسوب بنفسها فماذا لو أن أحد المخربين استطاع أن يركب برنامج على جهاز مستخدم عادي وبدلاً من أن يدير الذاكرة بدء يملئها بما لا يفيد مما سينعكس بالطبع على سرعة الجهاز بالسلب، هذه المشاكل تم حلها تماماً لأن من تولى زمام إدارة الذاكرة الآن هو ال .NET Framework بنفسه وتحديداً ال CLR داخل ال .NET Framework

    · لن يقع المستخدم في حيرة من أمره إن ظهر له رسالة تحذير من أن هناك برنامج يحاول تبديل واحدة أو أكثر من مكتبات النظام System DLL بواحدة أخرى أقدم ، فجميع برامج الدوت نت تستعمل ال BCL وهي موحدة على جميع الأجهزة ولا تختلف من جهاز لآخر

    3- الهدية الثالثة حملها إلي البرنامج نفسه فلم يعد البرنامج يخزن بداخله جميع مكوناته فهو يحمل فقط الكود الذي كتبه المبرمج بيديه فقط أما كود إدارة الذاكرة فسيجده أينما يتم تركيبه موجود في ال .NET Framework وكود الفئات Classes التي يستخدمها من ال BCL سيجده أيضاً أينما تم تركيبه موجودا في ال .NET Framework

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

    السلام عليكم ورحمة الله وبركاته

    احتجت في تطبيق ويب أبنيه أن اتأكد من ان المستخدم لن يستخدمه من أكثر من نافذة واحدة فقط حتى لا تتضارب ال Sessions ids

    وكان هذا أبسط كود وصلت له

     1: public partial class _Default : System.Web.UI.Page


     2: {


     3: protected void Page_Load(object sender, EventArgs e)


     4: {


     5: // without this step asp.net 2.0 will always generates new session id


     6: if (Session["ActiveSessionID"] == null)


     7: {


     8: Session["ActiveSessionID"] = Session.SessionID;


     9: }


     10:  


     11: HttpCookie activSessionCookie = Request.Cookies["ActiveSessionID"];


     12: if (activSessionCookie == null)


     13: {


     14: HttpCookie cookie = new HttpCookie("ActiveSessionID", Session.SessionID);


     15: cookie.Expires = DateTime.Now.AddDays(1);


     16: Response.Cookies.Add(cookie);


     17: }


     18: else if (activSessionCookie.Value != Session.SessionID)


     19: {


     20: Response.Write("this is new window");


     21: }


     22: }


     23: }


    أسهل طريقة لمنع المستخدم من تشغيل أكثر من نسخة من البرنامج

     1: static class Program


     2: {


     3: private const string concurrencyMtxNameM = @"onlyOne"; 


     4: static bool firstInstance = false;


     5: static Mutex concurrencyMtxM;


     6:  


     7: [STAThread]


     8: static void Main()


     9: {


     10: concurrencyMtxM = new Mutex(true, concurrencyMtxNameM, out firstInstance);


     11:  


     12: if (!firstInstance)


     13: {


     14: MessageBox.Show("Only one instance allowed");


     15: return;


     16: }


     17: Application.EnableVisualStyles();


     18: Application.SetCompatibleTextRenderingDefault(false);


     19: Application.Run(new Form1());


     20: }


     21: }




    المصدر : . NET - How to prevent running multiple instances of the same application


    ملاحظة: الوصلة باللغة الإيطالية يمكنك استخدام مترجم جوجل لقراءتها باللغة الانجليزية

    صفحات