Saturday, December 30, 2017

هندسة البرمجيات بالهجايص -- (2) أحط الحاجة فين؟

أصل المقالة دي كانت بوست كتبته على الفيسبوك، فحبيت أعيد نشره لتعم الفائدة...
وده رابط الحلقة الأولى في السلسلة لمن أراد..
"جيت ألم البنطلون الجاكتة ضربت...جيت ألم الجاكتة البنطلون ضرب!" -- سمير غانم 
- الحقيقة احنا بنشوف المرار في البرمجة، تيجي تعدل في حتة في البرنامج ولا تحل bug تلاقي جحيم اتفتح عليك و عمال تعدل في حتة تانية ورا حتة تالتة ورا حتة رابعة. وبيبقى فيه حتت كده في كل برنامج عبارة عن كهف مظلم محدش يجرؤ يقرب له بسبب موضوع تسلسل التعديلات ده. النوع ده من البرامج بيبقى مقاوم للتغيير، بيبقى عامل زي الزجاج كده فيه صلابة rigidity بس فيه هشاشة في نفس الوقت fragility. الوضع ده لما بيكون صفة ملازمة للبرنامج غالبا هاتفكر تهده وتبنيه من أول وجديد، إوعى، وراجع مقالة "إعادة اختراع العجلة في البرمجيات

- فيه برامج تانية بتبقى حلوة وظريفة وشغالة لكن لما بنحب نعيد استخدام الكود ده - حتى لو بعمله copy/paste بلاقيه مش بيشتغل. ممكن يكون لأنه مش مصمم إنه يعاد استخدامه - وده مش عيب بالمناسبة - وممكن يكون بسبب اعتماد أجزاء الكود على بعضها dependencies. برضو فكرة الاعتمادية في حد ذاتها مش مشكلة، المشكلة في كثرة عدد الحاجات اللي معتمدة على بعضها وعمق درجة الاعتمادية دي يعني بتعتمد على حاجات كتير اللي هي بدورها بتعتمد على حاجات كتير برضو..وهكذا. النوعية دي من التصميمات البرمجية بتتسم بصفة الجمود immobility.

- فيه نوعية تالتة من البرامج لما تحب تعدل فيها أو تحل مشكلة تلاقي الطريقة الصحيحة لعمل ده صعبة بسبب اعتمادية أجزاء الكود على بعضها، و تلاقيك بتكتب hacks و workarounds أكتر ما بتكتب كود كويس. الكود اللي من النوعية دي بيتصف باللزوجة viscosity يعني بيبقى ملزق كده زي الزيت لما يكون في الطاسة، لما تيجي تنظفه تلاقيه مش راضي يطلع.

البرامج اللي بيجتمع فيها البلاوي اللي فوق دي فيه مصطلح ظريف بيعبر عنها اسمه Big Ball Of Mud يعني كرة الطين الكبيرة!
لو تلاحظ المشاكل اللي فوق دي هاتلاقي إن الاعتمادية dependencies هي جزء أساسي في المشكلة، مش الاعتمادية في حد ذاتها، لكن كثرة الاعتمادية و عمقها - زي ما اتكلمنا فوق - و جزء أساسي في شغلك لما تيجي تظبط برنامج مطين أو تصمم برنامج جديد إنك تكسر الاعتمادية دي، و ده موضوع المقالة دي...أحط الحاجة فين؟

- أول مبدأ معانا هو مبدأ الفصل بين المسئوليات Separation of Concerns [الترجمة متصرفة أنا عارف].

تعالوا نضرب أمثلة توضح المقصود على طول:
= لما بيكون المشروع بتاعك مقسم لطبقات layers ما تخليش مسئوليات الطبقات تدخل في بعضها، يعني مثلا الطبقة بتاعت الواجهة front-end/presentation layer تكون مسئولة بس عن واجهة المستخدم user interface ومافيهاش قرارات ليها علاقة بقواعد النظام business rules و طبعا مش بتوصل لقاعدة البيانات! ده على مستوى بنية النظام application architecture.
= في كل طبقة layer ما تجيش تخلط برضو بين المسئوليات في أجزاء الطبقة دي، يعني مثلا يفضل إنك ما تكتبش html و css و javascript في نفس الملف لأن كل حاجة من دول مسئولة عن حاجة مختلفة. و نفس الكلام لما يكون عندك مثلا class مسئولة عن إدارة حسابات المستخدمين ما تحطش فيها كود له علاقة بإدارة الكتب (لو أنت عامل برنامج لمكتبة مثلا).
= نفس الكلام في قاعدة البيانات، ما تجيش تحط حقول columns مالهاش ارتباط الprimary key (و دي اسمها database normalization بس مش هانتكلم عنها عشان دي قصة لوحدها)
...وهكذا في كل مناحي البرنامج.

- المبدأ ده يقودنا لمبدأ تاني هو التخصص الدقيق Single Responsibility Principle [الترجمة متصرفة جدا المرة دي أنا عارف].

المبدأ بيقولك أي جزء برمجي لازم يكون بيعمل حاجة واحدة بس، و بيعملها كويس. و تقدر تقيس الموضوع ده بإن ما يكونش عندك أكتر من سبب لتغييرالجزء البرمجي ده. تعالوا نخش في الأمثلة:
= عندي method اسمها ParseAndCalculate لاحظ وجود الAnd في الاسم ده دليل على إن الmethod بتعمل حاجتين. طبعا الاسم مش دليل كافي، ممكن يكون مسميها بلحة وبتعمل 5 حاجات. الشاهد إن لما أحب أغير في الParse هاعدل في الmethod ولما أحب أغير في الcalculate هاغير فيها برضو، و ده يتنافى مع مبدأ التخصص الدقيق.
= شفت كود الmethod فيت تتجاوز ال3000 سطر بدون أي مبالغة، بس الحقيقة المبرمج حاطط comments كتير وعامل regions جوه الmethod مبين فيها كل حتة بتعمل إيه. ده مؤشر ظريف إن ممكن الregions دي تتقسم لmethods منفصلة.
= الكلام ده لا يسري على الmethods بس، طبقه بقى على كل حاجة من أول بنية النظام و طبقاته، مرورا بالclasses و الmethods و وصولا لقاعدة البيانات.

- فيه مبدأ تالت مرتبط بالمباديء اللي فاتت دي، ألا و هو مبدأ الاقتران Coupling و التماسك Cohesion [بتتنطق كده كوهيجن، بتعطيش الجيم]. يعني إيه الكلام ده؟

= الاقتران coupling معناه قد إيه الحاجات اللي أصلا مالهاش علاقة ببعض في اعتمادية بينها، و دي قصة الdependencies اللي عمالين نهري فيها فوق، فده بيتكلم عن علاقة الحاجات ببعضها من بره.
= أما التماسك cohesion فبيتكلم عن علاقة الحاجات ببعضها من جوة، يعني لما تشوف حاجة في الclass كده و تقول: "إيه اللي جاب القلعة جنب البحر؟" تعرف إن الclass مش متماسكة و بتعمل حاجات مش بتاعتها.
المبدأ ده تقدر تعتبره معيار لقياس هل تغيير الكود بتاعي سهل و لا صعب، إزاي؟
= الحاجات اللي مقترنة ببعضها tightly coupled بتبقى صعبة التعديل، يعني فيه اعتمادية بينها بحيث لو عدلت في جزء محتاج أعدل في جزء تاني. و أنا مش عاوز كده أنا عاوز الارتباط بينها يكون في حده الأدنى loosely coupled.
= الحاجات اللي مش بتطبق مبدأ التخصص الدقيق بتكون غير متماسكة loosely cohesive ودي برضو بتبقى صعبة في التعديل، يعني فيه أكتر من سبب لتعديل الجزء البرمجي ده. و أنا مش عاوز كده برضو، أنا عاوز التماسك يكون عالي جدا tightly cohesive.
= طيب تعالوا نعيد صياغة المبدأ تاني: حاول توصل لأعلى تماسك و أقل ارتبط strive for tight cohesion and loose coupling عشان الكود بتاعك مايبقاش big ball of mud.

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

Sunday, December 24, 2017

إعادة اختراع العجلة في البرمجيات

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

- أول مهمة عمل استلمتها في أول شركة اشتغلت فيها كان مطلوب مني أكمل شغل حد كان بدأ فيه قبلي شوية صغيرين، فأنا بكل ثقة، و كعادة كل المبتدئين قليلي النضج، ما عجبنيش الشغل اللي معمول و هدّيته وبنيته من أول وجديد، وطبعا ده أخد وقت محترم عشان أخلصه.
المهم مديري الفني وقتها كان م. حسن فهمي - ربنا يجزيه عني خيرا - سابني أكمل الشغل لغاية الآخر و بعدين قال لي الآتي:
مش كل حاجة ما تعجبكش تهدها وتبنيها من أول وجديد.
وده كان أول درس عملي لي في البرمجة.
وقتها ما استوعبتش الدرس قوي عشان كنت لسه قليل الخبرة، بس الأيام بتعدي و بتعلم الدرس بالطريقة الصعبة.
- في سبعينيات القرن الماضي، واحد من رواد صناعة البرمجيات اسمه فريدريك بروكس، عمل كتاب اسمه The Mythical Man-Month بيتكلم فيه عن مشكل صناعة البرمجيات وقتها، و الكتاب ده يعتبر من كلاسيكيات الصناعة بتاعتنا وظريف جدا، أنصحكم تقرأوه. المهم الراجل حذر في الكتاب ده من حاجة غريبة جدا، ألا وهي تأثير النظام الثاني The second system effect، و خلاصة الكلام اللي قاله إنه لما يكون عندك برنامج فيه مشاكل و تيجي تعمله من أول وجديد غالبا البرنامج ده هايكون فاشل لأنك هاتحاول تعالج فيه كل المشاكل اللي قابلتك في المشروع الأول و المشاكل اللي متوقع تقابلك مستقبلا و بالتالي هاتهندسه بزيادة over-engineered!
الحقيقة لما قرأت الكلام ده أول مرة استوعبته كويس المرة دي عشان كنت مريت بتجارب عملية على مشروعات فشلت بتأثير النظام الثاني!
- طيب ليه المبرمجين بيحبوا يهدوا اللي معمول و يبنوه من أول وجديد على نظافة -زعموا-؟

فيه مثل عندنا بيقولك: مفيش صنايعي بيعجبه شغل صنايعي تاني. والكلام ده في صناعة البرمجيات له وجه للأسباب التالية:
1- غالبا كل برنامج اتعمل كان له سياق ومشاكل بيحاول يحلها و مبرمجين بخبرات معينة بيشتعلوا عليه ومش شرط أنت تكون ملم بالظروف و السياق ده، و لا عندك نفس الخبرة اللي كانت عند الناس اللي عملوا البرنامج، ربما خبرتك أكتر فتستحقر شغلهم، وربما أقل فتحس إنه خيال علمي.
2- البرنامج مش بيتوقف بعد أول طلعة، و بيفضل يتضاف فيه خصائص و حلول لمشكلات bug fixes و تعديلات بشكل مستمر. مع ضغط الوقت و قلة الخبرة و تغير مطاليب العملاء بتلاقي الدنيا بتعك منهم.
3- فيه خاصية من طبائع البرمجيات، أشار ليها جول سبولسكي - أحد مؤسسي موقع stackoverflow الشهير، و هي أن كتابة الكود أسهل من قراءته، والطبيعة دي بتسري حتى لو أنت بذات نفسك اللي كاتب الكود اللي مش عارف تقرأه ده!
4- فيه مشكلة بقى عند المبرمجين نفسهم لما بييجوا يقيموا برنامج مش هما اللي عاملينه، و هي معايير التقييم: فمثلا ما بيحطوش وزن للسياق اللي اتعمل فيه البرنامج - اللي اتكلمنا عنه في النقطة 1، أو بيقيموه حسب التقنيات الحديثة اللي هما بيعرفوها، و اللي ربما ما كانتش موجودة لما البرنامج اتعمل أول مرة، أو حسب أساليب التصميم الحديثة اللي ما كانتش موجودة برضو لما البرنامج اتعمل أول مرة.
4- في بقى مشكلة تانية عند بعض المبرمجين المطلعين، إنهم بيحبوا يعملوا الحاجة من أول وجديد عشان يجربوا كل حاجة جديدة عشان يكتبوها في سيرهم الذاتية، و على الرغم إن تجربة كل شيء جديد أحد أساليب التعلم اللي فادتني كتير على المستوى الشخصي، بس كانت مكلفة، لأني فشلت كتير بسبب الاعتماد على تقنيات غير ناضجة، أو تجربة حل برمجي للمشكلة الغلط! وكل ما بتزداد خبرتي الموضوع ده كان بيقل معايا.
- طبعا الحل الأمثل لما يكون عندي برنامج خربان بس شغال وله قمية عند العملاء إني أحسن فيه واحدة واحدة، وحتى لو هاعيد بناؤه من الصفر، فلازم ده مايكونش خبطة واحدة، بل يكون التغيير بطيئا ومع الوقت.
- فيه برنامج كنت شغال على النسخة التانية منه، زمايلي كانوا بيقولولي إنهم اكتشفوا في النسخة الأولى منه إن الفيجوال بيسك ما بيقبلش أكتر من 128 بارامتر في الفانكشن (لاحظ اكتشفوا، يعني فضلوا يجربوا لغاية لما فشلوا). و مشروع تاني مش كبير كان بياخد 160 جيجا رامات، و لما حسنوه وصل ل70 جيجا!!
طبعا النوعية دي من البرامج لازم تولع فيها و تنسى كل الهري اللي أنا قلته فوق ده، بس لو عرفت تظبطه بالتدريج يبقى أحسن 
يللا شير في الخير بقى 

Wednesday, December 6, 2017

هندسة البرمجيات بالهجايص: (1) أسمي الحاجة إيه؟

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

* مقدمة:

بقالي كتير عاوز أكتب سلسلة مقالات أو أعمل سيشنز عن بعض المفاهيم المهمة في تصميم البرمجيات، و بالذات المفاهيم المتعلقة بال Object Oriented Design و ما يتبعها من Design Patterns، بس كالعادة الوقت ما بيبقاش متاح، فقلت أعمل سلسلة على الفيسبوك أتكلم فيها عن المفاهيم دي بالهجايص كده، و أهو أحسن من مفيش.

* مين هايستفيد من الهري ده؟

عشان يكون الكلام مفيد لازم اللي هايقراه يكون عنده خلفية جيدة عن الObject Oriented Programming و إلا هايحس في معظم الأحيان إننا بنتكلم هيروغليفي.

* أول قاعدة:

خلونا نبدأ في الأول بمفاهيم عامة في تصميم البرمجيات و نخش في التفاصيل واحدة واحدة مع الوقت إن شاء الله.
من أهم الحاجات اللي محتاجين ناخد بالنا منها لما نعوز نكتب كود نظيف:
1- نسمي الحاجة إيه؟
2- نحط الحاجة دي فين؟
[الحقيقية اللي اتعلمت منه القاعدة دي واحد ابن حلال اسمه أمير جعفر عامل سلسلة يتيمة على اليوتيوب عن الTest Driven Development (ابقوا بصوا عليها)]
نرجع لشرح المفهوم...

*** نسمي الحاجة إيه؟

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

* إزاي بقى تختار اسم مناسب؟

- الاسم لازم يعبرعن الحاجة اللي بيمثلها، يعني مثلا لو بتختار اسم لclass فالمفروض تفهم من اسمها الكلاس دي بتهبب إيه بالضبط، لو اسم method فالمفروض الاسم يعرفك هي بتعمل إيه بالضبط من غير ما تبص على الكود اللي جواها...إلخ. و خدها قاعدة كده، لو الاسم اللي اخترته محتاج تكتب جنبه comment عشان يشرح معناه إيه، فده مؤشر إن الاسم اللي أنت مختاره وحش.
- بلاش الأسماء المضللة عشان بتتعبنا و الله، يعني مثلا ماتجيش تسمي variable: productList و هو مش list مش جايين نحل فوازير احنا...لقد هرمنا 
- الفرق بين المفاهيم لازم ينعكس في الأسماء، يعني مثلا لو بنعمل method بتنقل ملف من source إلى destination، ما تسميش الvariables:
a1 & a2
لأ سميهم source & destination
- تجنب التلوث البصري في اختيار الأسماء، يعني مثلا لو عندك class اسمها company، ما تجيش بقى في كل الfields اللي فيها و تلزق في اسمها company، فماتقولش companyName، companyId، companyAddress..إلخ. قل لي إيه الإضافة اللي ضفتها لما عملت كده؟ و الأنيل بقى لما تلاقي واحد كاتب لك nameString كأن الاسم ممكن يكون float مثلا.....لقد هرمنا بجد 
- الاسم اللي هاتختاره لازم تكون هاتعرف تقراه، و بالتالي لما تيجي تدور عليه تعرف تلاقيه. بلاش اختصارات في الأسماء، و استخدام الأسماء الطويلة مش عيب و لا حرام على فكرة.
- استخدام الفرانكو في الفيسبوك وحش قوي، و أوحش في الكود. دونت يوز فرانكو إن يور كود بلييييييزززز.
- بلاش أرقام سحرية في الكود، أرقام مستخدمة في كل الكود كده محدش عارف معناها إيه. في اختراعات ظريفة في لغات البرمجة دلوقتي زي الenums و الconstants، المبرمجين الكويسين بيستخدموها...كن مبرمجا كويسا زيهم.
- ما تستخدمش variables من حرف واحد إلا في الloops، عشان دي من الحالات القليلة اللي المبرمجين تلقوها بالقبول.
- أسماء الclasses و الobjects تكون أسماء مش أفعال، مثال: company، account، FileParse. و أسماء الmethods تكون أفعال و أسئلة مش أسماء، مثال: DoSomething، IsValid، HasChildren..إلخ.
- بلاش استظراف في الكود، ما تجيش مثلا تستخدم قفشات من فيلم بتحبه في أسماء الvariables عشان أنت أكيد عارف إن مش كل الناس بتلقط قفشات الأفلام.
- حاول تكون متسق مع ذاتك و تستخدم نفس الاسم للتعبير عن نفس المفهوم في كل حتة، يعني مثلا لو بتحب اسم get لما تعوز تجيب حاجة، افضل استخدمه في كل حته، مش مرة تستخدم get ومرة retrieve و مرة fetch... كمان مرة، خليك متسق مع ذاتك.
- لو مطبق design pattern معين حاول تستخدم اسمه كجزء من اسم الclass أو الmethod بتاعتك، و نفس الكلام لو فيه algorithm أو أي مصطلح يفهمه بتوع البرمجة برضو استخدم اسمه برضو. تذكر إن اللي بيقروا الكود مبرمجين فارفق بهم و ساعدهم يفهوا الكود عشان يدعولك.
- لو ما لقيتش اسم برمجي مناسب بس كان فيه اسم في البزنس اللي أنت شغال عليه ممكن تستخدمه، توكل على الله و استخدم اسم البزنس.
- و لو ما لقيتش اسم مناسب لا للمبرمجين و لا في البزنس، هاتضطر تطلع مهارات الفتي اللي جواك، بس حاول تقلل من استخدام الأسماء المستهلكة زي Manager، Controller، Data، Info بقدر المستطاع عشان كتر استخدامها عمال على بطال بقى مضلل شوية.
- لو اخترت اسم وبعد كده حسيت إنه مش مناسب غيره عادي خالص، مش عيب و الله، خاصة إن التولز دلوقتي بتسهل لك التعديل في كل الأماكن مرة واحدة. و لو غيرته 10 مرات و لسه مش مناسب افضل غير فيه ولا يهمك.
- حاول تقرأ كتاب clean code، أنا نقشت منه حاجات كتير في البوست ده. و دايما بقول لو المبرمج مش هايقرأ غير كتاب واحد في حياته في البرمجة فليكن الكتاب ده.

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

Thursday, September 14, 2017

Introduction to web applications performance

Introduction

The field of web application performance is huge and cannot be covered in a single article, especially when we talk about practical techniques to build fast applications. Thus, I will just scratch the surface of the topic to cover important concepts around performance like performance metrics, the difference between performance and scalability, and perceived performance.

Let's go...

Basic Concepts

Performance metrics

  • Response time: This is the most widely used metric of performance and it is simply a direct measure of how long it takes to process a request.
  • Throughput: A straightforward count of the number of requests that the application can process within a defined time interval. For Web applications, a count of page impressions or requests per second is often used as a measure of throughput.
  • System availability: Usually expressed as a percentage of application running time minus the time the application can’t be accessed by users. This is an indispensable metric, because both response time and throughput are zero when the system is unavailable. Most companies use this as a way to measure uptime for service level agreements (SLA).
  • Responsiveness: is about how quickly the system acknowledges a request as opposed to processing it. This is important in many systems because users may become frustrated if a system has low responsiveness, even if its response time is good. If your system waits during the whole request, then your responsiveness and response time are the same. However, if you indicate that you've received the request before you complete, then your responsiveness is better. Providing a progress bar during a file copy improves the responsiveness of your user interface, even though it doesn't improve response time.
  • Requests Rate: Understanding how much traffic your application receives can be useful to correlate to other application performance metrics to understand the dynamics of how your application scales. The more requests users send to the application, the higher the load. As load increases, performance decreases. A similar but slightly different metric to track is the number of concurrent users.
  • Resources Consumption: Measuring resources (CPU, Memory, and disk space) in correlation to other metrics - like response time or throughput - is very important in resource planning for scalability.
  • Efficiency is performance divided by resources. A system that gets 30 transaction per second (tps) on two CPUs is more efficient than a system that gets 40 tps on four identical CPUs.
  • Latency is the minimum time required to get any form of response, even if the work to be done is nonexistent. It's usually the big issue in remote systems. If I ask a program to do nothing, but to tell me when it's done doing nothing, then I should get an almost instantaneous response if the program runs on my laptop. However, if the program runs on a remote computer, I may get a few seconds just because of the time taken for the request and response to make their way across the wire. As an application developer, I can usually do nothing to improve latency. Latency is also the reason why you should minimize remote calls.
  • Server response time measures how long it takes to load the necessary HTML to begin rendering the page from your server, subtracting out the network latency between the browser and your server.

What is performance?

Performance is either throughput or response time—whichever matters more to you (In Web Applications, response time is more popular). It can sometimes be difficult to talk about performance when a technique improves throughput but decreases response time, so it's best to use the more precise term. From a user's perspective responsiveness may be more important than response time, so improving responsiveness at a cost of response time or throughput will increase performance.

What is scalability?

Application performance will always be affected by resource constraints. Scalability is the ability to overcome performance limits by adding resources.  No matter how much hardware we have at a certain point we will see decreasing performance. This means increasing response times or a limit in throughput. Will adding additional hardware solve the problem? If yes, then we can scale. If not, we have a scalability problem. In other words, Scalability is a measure of how adding resources (usually hardware) affects performance. A scalable system is one that allows you to add hardware and get a commensurate (متناسب) performance improvement, such as doubling how many servers you have to double your throughput. Vertical scalability, or scaling up, means adding more power to a single server, such as more memory. Horizontal scalability, or scaling out, means adding more servers.

Will scaling solve performance problems?

Ideally yes, but practically resources constraints may not be the issue! For example, if resources are not overloaded then adding more resources will not solve performance problems because they are not the bottleneck. If you add resources and didn’t get commensurate performance improvement, you have a performance issue.
The rules here:
  1. If adding more resources can solve performance issue, go for it; Developers are expensive and hardware is cheap.
  2. When adding resources became expensive, or does not help in the issue, enhance performance and efficiency.


How to define an application performance?

It is common to define application performance like “Response time is 2 seconds”.
But this not descriptive enough, especially in scalability planning context. It is better to say: “System response time is 2 seconds at 500 concurrent requests, with a CPU load of 50%, and a memory utilization of 92%”.

Performance Tests

To make accurate performance definition, we should do some performance tests:

Load Test

Load testing is the simplest form of performance testing. A load test is usually conducted to understand the behaviour of the system under a specific expected load. This load can be the expected concurrent number of users on the application performing a specific number of transactions within the set duration. This test will give out the response times of all the important business critical transactions. The database, application server, etc. are also monitored during the test, this will assist in identifying bottlenecks in the application software and the hardware that the software is installed on.

Stress Test

Stress testing is normally used to understand the upper limits of capacity within the system. This kind of test is done to determine the system's robustness in terms of extreme load and helps application administrators to determine if the system will perform sufficiently if the current load goes well above the expected maximum.


Responsiveness as perceived performance

While response time - for example - is important to measure performance, it’s important as well to remember that users are the ultimate judge of performance. As users are not clocks, their time perception may be different from what we measure empirically.
In judging system responsiveness, we must first know how fast users expect a system to be. Research shows that there are four main categories of response times:
  • We expect an instantaneous response, 0.1 to 0.2 milliseconds, for any action similar to a physical interaction. Pressing a button, for example. We expect this button to indicate that it is pressed within this time.
  • We expect an immediate response, within a half to one second, indicating our information is received. Even in the case of a simple interaction, we expect an actual response to our request. This is especially true for information we assume is already available, as when paging or scrolling content.
  • We expect a reply within 2 to 5 [or better 3] seconds for any other interactive request. If the response takes longer, we begin to feel that the interaction is cumbersome. The more complex we perceive a task to be, the longer we are willing to wait for the response.
Simple UI tricks, such as progress bars, redirecting users’ attention using animation, or placing slower loading sections at the bottom of a page or offscreen, can often ‘fix’ a performance problem without the need to tune the underlying code. These UI tricks are an important tool to have in your performance tuning toolbox and can be much quicker and easier than addressing the underlying issue. They can act as a holdover until you have the time to devote to the core problem.

How can we measure perceived performance?

As with performance, human perception for faster or slower is not as precise as technical measurements. This is very important when judging whether a performance optimization is worth the effort.
In essence, our limited perception of application responsiveness can’t detect performance changes of much less than 20%. We can use this as a rule of thumb when deciding which improvements will impact users most noticeably. If we optimize 300 milliseconds a request that took 4 seconds, we can assume that many users will not perceive any difference in response time. It might still make sense to optimize the application, but if our goal is to make things faster for the users, we have to make it faster by at least 0.8 seconds.

References


Thursday, August 10, 2017

Deconstructing Docker on Windows



“A problem well stated is a problem half solved.” –Charles Kettering[1]

Docker gained much traction during the last period, and it seems it is the right time to start learning it, especially after it became natively supported in Windows.
All my knowledge about docker and containers world is vague, I read a bunch of articles and watched few videos here and there about the topic but didn't have a solid understanding or practical usage yet.

My Goal

I have many .NET 4.x web applications, read: .NET 4.x not .NET Core, and I have some pain in automating their deployment. I want to start hosting these applications in Docker hoping to relieve my pains and gain all the benefits promised by Docker world.

From Where to start?

Well, I have read an interesting book about rapid skills aquisition named: The First 20 Hours: How to Learn Anything . . . Fast!  (You can read its summary here). The author of the book mentioned some steps to acquire any new skill quickly:

  1. Deconstruct it into the smallest possible sub-skills.
  2. Learn enough about each sub-skill to be able to practice effectively and self-correct.
  3. Remove any physical, mental, or emotional barriers that get in the way of practice.
  4. Practice the most important sub-skills for at least 20 hours.

And from step 1 I will start with listing all the skills I think will help me in understanding and applying Docker to achieve my goal.

The Plan

I hope I can find enough time to write about each of these skills in detail, but unfortunately, I am a busy developer, but I will try to -at least- updating this article with useful links that may help.

Docker Skills Deconstructed

Basic Concepts

  • What are containers? And how do they work?
  • What is the difference between containers and virtual machines?
  • What is Docker? And how does it work?
  • What is the difference between Docker on Linux and Docker on Windows?
  • What are the jargon needed to work with containers/docker?
  • What is the benefits of using containers/Docker for development, operations, security, etc.?
  • What are other alternatives to Docker?
  • What are containers available on Windows?

Maturity

  • Who uses Docker?
  • Who uses Docker on Windows in production?

Installation

  • Which Windows version supports containers/Docker?
  • What are the prerequisites to install Docker?
  • How to install Docker on Windows?

Interacting with Docker


  • Do we have UI to work with Docker or we must use command line?
  • Can we integrate with Visual Studio?

Installing Software

  • How can I install a software inside Docker? Like IIS, SQL Server, etc?
  • How to create a base image that contains all the software I need (IIS, SQL Server, .NET Framework, etc)?
  • Can I install development tools on containers, like Visual Studio, SQL Server Management Studio, IIS Manager, etc?

Development

  • Create a Hello World ASP.NET 4.6 application and host it on docker.
  • How to host an existing large web application in docker?
  • How can I debug issues on containers?

Deployment

  • How can I host my web application inside docker?
  • How can I host a windows service in Docker?
  • How can I host my database inside Docker?
  • How can I host my files inside Docker?
  • Can I host all the layers of my application in one Docker image? 
  • How can Docker help me in automating deployment?
  • Can I use Windows Explorer, IIS Manager, and SQL Server Management Studio in my machine to manage files, web applications, and databases hosted in containers?

Networking

  • How to assign an IP to a docker image?
  • How containers can talk to each other?
  • How to add this image to an existing Web Farm?
  • How to create a web farm using only containers?

Infrastructure

  • How resources are managed by the image? i.e. what if my application hosted in Docker needs more CPU or memory, how the host manages it?
  • Does Containers restarts automatically with Windows?
  • can I build my private cloud with Docker?


Managing Docker Images

  • How can I copy downloaded images to other machines?
  • How can I create my own private docker hub?
  • How can I add images to source control?

Side Skills To Learn

  • PowerShell

Misc

  • Create a cheat sheet for Docker commands - if not exists -

-------
[1] Source: The first 20 Hours book

Friday, March 10, 2017

ما أهمية تقسيم المشروع لطبقات layers and tiers؟

من فترة كان فيه سؤال على المجموعة Egpytian Geeks على الفيسبوك عن أهمية إني أقسم المشروع بتاعي لlayers و tiers, و هل ده هايأثر على سرعة و أداء التطبيق و لا إيه اللي هايحصل؟
ساعتها كنت كتبت كلام كتير و افتكرته دلوقتي، فقلت أظبطته شوية و أعيد نشره على صفحتي على الفيسبوك لتعم الفائدة، ثم نصحني بعض الأصدقاء بإعادة نشره المدونة دي, و عشان كده مكتوب بالعامية...
و أصل النقاش كان هنا لمن أراد الاطلاع عليه.

الفرق بين الlayers و الtiers

خلينا الأول نبين الفرق بين الtier و الlayer. الاتنين طبقات, بس لو الطبقات بيشتغلوا على نفس الكمبيوتر يبقى اسمهم layers, لو انفصلوا يبقى اسمهم tiers. بعبارة أخرى, الlayers هي logical separation أما ال tiers فهي physical separation.

هل الطبقات دي هاتأثر على طريقة أداء المشروع؟

آه طبعا...
- هاتبطأه (و لو قليلا في حالة الlayers (فيمكن إهماله) و كثيرا في حالة الtiers)
- هاتخليه أصعب في الفهم و الdebugging: تخيل إنت عمال تتنط بين الlayers عشان توصل للbug أسهل و لا لو هي ف نفس المكان معاك أسهل؟
- هاتكبر المشروع: هاتزود tier يعني هاتعمل project منفصل لكل tier و هاتحتاج تزود  web services...إلخ, و ده طبعا هايصعب الدنيا أكتر
- فيه ناس هاتقول لك هاتقدر تعيد استخدام الطبقات دي في مشاريع تانية، و الفكرة دي تسمى  reusability ، و دي انساها خالص مش هاتحصل!!! -- هاتيجي بالتفصيل تحت - إن شاء الله -
أمال ليه وجع القلب ده؟!!!
 خلينا ناخد شوية تفاصيل عشان نعرف الفايدة الحقيقية...

ليه بقسم المشروع لطبقات؟ 

 - فيه نظرية عامة في هندسة البرمجيات بتقول: إن أي مشكلة في تصميم البرامج ممكن أحلها بإضافة طبقة غير مباشرة - و الاستثناء الوحيد هو مشكلة كثرة الطبقات غير المباشرة -
 We can solve any problem by introducing an extra level of indirection....except for the problem of too many levels of indirection
ممكن تقرأ المزيد عن النظرية دي هنا

يعني إيه الكلام ده؟

 يعني أنا عندي فورمة عليها شوية كونترولز, و عندي قاعدة بيانات, ليه ما بندهش لقاعدة البيانات على طول و أريح دماغي؟
 عشان أنا عندي مشكلة (أو عدة مشاكل) عاوز أحلها, و بتطبيق النظرية السابقة, رحت عامل طبقة حطيت فيها شغل الداتابيز, و طبقة حطيت فيها البزنس بتاعي, و خليت الطبقة اللي فيها الUI بسيطة لا بتهش و لا بتنش!

طب إيه هي المشاكل اللي عاوز أحلها دي؟

تخيل الآتي:
إني لو جبت الكود بتاع البزنس + الكود بتاع الداتبيز + الكود بتاع الuii و حطيتهم في حتة واحدة, فكر معايا إيه اللي هايحصل في السيناريوهات دي:
1- كنا شغالين ال UI بasp.net web forms بس مايكروسوفت عملت حاجة جديدة اسمها asp.net mvc بس لما جيت أطبقها ما عرفتش عشان الكود ملخفن!
2- البرنامج كان صغير, و كنا شغالبن أكسس, بس لما كبر البرنامج أكسس ما استحملتش, فقلنا لازم نستخدم sql server بس ما عرفناش عشان الكود بتاع الداتابيز معتمد على أكسس, و ملخفن جوة الكود بتاع الui و محتاج تعديلات في حتت كتيرة!
3- البرنامج كان شغال desktop بس برامج الdesktop بقت ميتة, و كل الناس متجهة نحو الويب و الموبايل, و أنا كاتب كود بقالي سنين كتيرة و حرام أرميه, و أبدأه من أول و جديد, و مش عارف أسلكه من الكود الملخفن!
 .. الأمثلة من دي كتيرة, الشاهد: إن فكرة تقسيم البرنامج لطبقات فوق بعض بتديني ميزة تسهيل استبدال أي طبقة (نوعا ما) , و ده اللي بنسميه design for replacement not reusability!
لاحظ هنا إني حصلت على ميزة سهولة الاستبدال replacement مش سهولة إعادة الاستخدام reusability، طب إيه الفرق بينهم؟
الأولى تعني *إعادة الاستخدام* يعني عندي layer هاستخدمها ف حتة تانية
أما الثانية فتعني *الاستبدال*, يعني عندي layer هارميها و أجيب واحدة بدالها
اسأل أي واحد عمل كام مشروع وييب, كام مرة أخد Layer ك dlll و أعاد استخدامها في مشروع تاني؟ عمر ده ما حصل معايا أنا - على الأقل -! أقصى ما فعلته إني أخدت شوية كود copy/paste و استخدمتهم في مشروع تاني. و ده ما اسمهوش reusability ده اسمه code duplication و ده ربما يكون مصدر كل الشرور في البرمجة - كما قال روبرت مارتن!
لكن كام مرة احتجت إني استبدل layer فيها مشاكل بlayer تانية لسبب أو لآخر؟ ده حصل معايا كتيييير. عشان كده بقول لك design for replacement not reusability و ده بيفرق على فكرة في طريقة التصميم نفسها, بس ده مش مجاله دلوقتي.

طب إزاي حصلت على ميزة القابلية للاستبدال دي؟

بإني خليت كل طبقة تعمل حاجة واحدة بس, و بالتالي بقى فيه سبب واحد للعب في الطبقة دي.
مثلا: طبقة الpresentation بقت مش هالعب فيها إلا لما عاوز أعدل حاجة في طريقة العرض أو استبدلها كليا, و ده من غير ما قاعدة البيانات تتأثر. و نفس الكلام بينطبق على الطبيقات التانية.
و ده اللي بنسميه separation of concerns و فيه رواية أخرى  single responsibility principle

مشكلة كمان...

 دلوقتي أنا حاطط كل الطبقات بتاعتي على كمبيوتر واحد, بس أنا خايف إن حد يقدر يخترق الكمبيوتر ده و يحصل على البيانات اللي متسجلة في قاعدة البيانات, إيه الحل؟
Add layers of indirection!
بس الطبقات اللي هاضيفها هنا هاتكون في الحقيقة tiers مش layers بحيث لو أي tier فيهم اتضربت compromised هايكون لسه عندي خطوط دفاع تانية (الtiers اللي ورا)!
و بمجرد ما أقسم البرنامج بتاعي لtiers هاتتفتح لي آفاق تانية مثيرة جدا!!!

نرجع لمشكلة البطء...

زي ما قلنا، إن أول حاجة هاتحصل لما أقسم البرنامج على أكتر من كمبيوتر tiers إن البرنامج هايبطأ شوية!
أيوة... عشان فيه وقت هايستهلك في إن الدااتا تتنقل من كمبيوتر للتاني عبر الشبكة.
 لو الكمبيوترين دول بعاد عن بعض, و عملية نقل البيانات هاتتم عبر الإنترنت فالدنيا هاتكون أبطأ مما لو كانوا على شبكة داخلية.
 بس عشان أتغلب على مشكلات البطء دي محتاج أظبط حتت كتير في البرنامج, يعني مثلا أعتمد كتير على client = javascript و الajax calls و في السيرفر أعتمد كتير على الasync calls و هاحتاج اعمل optimization للdatabase queries و أعمل caching للبيانات...إلخ و في الآخر الدنيا هاتظبط بصورة كبيرة.
بالرغم من إن سرعة البرنامج قلت (نوعا ما) إلا إني لما عملت tiers هاقدر دلوقتي أحسن اللscalability بتاعت البرنامج, وده هايحسن السرعة جدا!
 طب إزاي؟
الscalability قصة طويلة مش ده وقتها, بس خلينا نقول إن معناها قد إيه البرنامج بتاعي هايستحمل زيادة عدد المستخدمين؟
في حالة الكمبيوتر الواحد one tier قدرة البرنامج مرتبط بقدرة الكمبيوتر اللي هو شغال عليه. البرنامج هايفضل شغال معايا كويس و زي الفل لغاية لما عدد المستخدمين يوصل لحد معين بعده البرنامج سرعته هاتقل بصورة دراماتيكية (حلوة دراماتيكية دي :)
و الحل إما تزويد إمكانات الكمبيوتر أو تزويد الكمبيوترات.
فيه كلام هنا كتير web farms - web gardens ...إلخ, بس اختصارا, توزيع البرنامج هايسمح لي إني أعمل optimization لأجزاء معينة في البرنامج تحسن الscalability بتاعته.
طب السرعة هاتزيد و لا هاتقل, آخر كلام؟ :)
لو البرنامج بتاعك صغير و عدد المستخدمين صغير, هاتحس إنها بطيئة.
لو البرنامج بتاعك كبر, و عدد المستخدمين زاد هاتحس إنها أسرع.
 ---
و ده يقودنا إن للهدف الرئيسي من كل الحوارات دي: المرونة!
لما بقسم الدنيا لأجزاء أو طبقات بيبقى عندي المرونة اللي تخيني أعمل optimizations على كل جزء على حدة.
----
و كما يظهر من كل الهري ده, إني زودت الcomplexity بتاعت البرنامج بس في المقابل حصلت على مرونة: مرونة إني أستبدل بأجزاء تعبانة في البرنامج أجزاء كويسة , مرونة إني أظبط أجزاء في البرنامج من غير ما أؤثر على أجزاء تانية..إلخ.
 ---

طيب إمتى أعقد الدنيا كده؟

لازم أختم الكلام بإن إضافة الcomplexity دي على المشروع لازم تكون مبررة, يعني المشروع طول ما هو صغير (يتعمل في أيام) مفيش داعي إني أعمل الفصلة في الكود, أي عجن في الcontroller هايكون كويس
لو المشروع كبر شوية (يتعمل في أسابيع) هنا الlayers هاتكون مناسبة
لو كبر أكتر (يتعمل في شهور) هنا الtiers هاتكون مناسبة أكتر
... و هكذا
 أو بعبارة أخرى: الفائدة من الحوارات دي بتبان لما البرنامج يكبر, لكن طول ما هو صغير فهاتفضل تحس إنه صعبة و رخمة و مالهاش فايدة كبيرة!

ما هي فائدة الORMs؟

مقدمة

كان فيه نقاش على مجموعة Egyptian geeks حول فائدة الORMs. و لقيت إني كتبت كلام كتير، فهاعيد نشره هنا لتعم الفائدة...
و ده رابط النقاش الأصلي للي عاوز يطلع عليه.
طبعا أنا كنت قائل إني هاكتب على البلوج دي بالإنجليزي، بس لقيت نفسي مش بكتب بقالي كتير، و لما نشرت الكلام ده على الفيسبوك بعض الأصدقاء نصحوني إني أنشرها على مدونتي، و عشان كده مكتوبة باللغة العامية. و يارب تكون مفيدة.

أولا: إيه لازمة الORM؟ أو إيه هي المشاكل اللي بيحلها؟


* مشكلة رقم 1: impedance mismatch و دي لو أنت اشتغلت بالتقنيات القديمة (عصر ما قبل الorm) هاتلاقي إنك كنت دايما بتعمل class و تعبي فيها النتائج بتاعت الكويريز بتاعتك، و ده أمر مرهق جدا، الorm عملهولك ببساطة. ميزة إضافية هنا إنك ممكن تربط الclass بتاعتك بكذا جدول، أو جدول واحد يتفك ف كذا class


* مشكلة رقم 2: persistence ignorance و دي تعني إنك فعليا بتتعامل مع الobjects ككobjects بعض النظر هي جاية من داتابيز و لا من ملف، و بغض النظر نوع الداتابيز دي إيه أو الملف ده إيه. دي مفيدة في بعض الحالات زي مثلا إني أغير قاعدة البيانات بتاعتي، و دي طوال سنين خبرتي لم تطلب مني إلا مرة واحدة بس!
* مشكلة رقم 3: كتابة و صيانة أكواد الsqll عملية مش لطيفة خالص، خاصة إن البزنس بتاعك بيبقى موزع على التطبيق و قاعدة البيانات، فالorm بيساعدك في تنفيذ الseparation of concerns و بيديك لغة زي ال sql بس غالبا بتكون statically typed و هذا يعني إنك ممكن تكتشف مشاكل الsyntax من غير من تشغل البرنامج، و فيه pattern مستخدم هنا اسمه object query pattern، و من أجمد التطبيقات للباترن ده: LINQ
* مشكلة رقم 4: الcaching: لما بتجيب حاجة من قاعدة البيانات، ليه تروح تجيبها تاني لما ممكن تحتفظ بيها طول الفترة اللي ممكن تحتاجها فيها؟ و عشان يعملوا الcaching ده فيه pattern بيستخدموه اسمه identity map. فيه مستويين من الcaching: المستوى الأول في الsession الواحدة، و دي موجودة في أغلب الorms. و المستوى التاني فيما بين الsessions المختلفة، و دي موجودة في بعض الorms. المستوى الأول بيسموه 1st level cache و المستوى التاني بيسموه 2nd level cache
* مشكلة رقم 5: أحيانا بيكون بيانات مرتبطة ببعضيها بس موزعة على كذا جدول، في الأول بتجيب الmaster record و بعدين بتكتب كويري منفصل عشان تجيب البيانات المرتبطة بيه من الجداول التانية. الموضوع ده بيبقى رخم لما بيبقى كتير. الorms جواها lazy loading implementation عشان يسهل عليك الحوار ده: البيانات المرتبطة هي عبارة عن reference to object و أول ما بتستعمله الorm بتروح تجيبهولك من غير ما أنت تبذل أي مجهود.
ده لذيذ جدا لغاية لما تخبط في مشكلى اسمها n+1: و دي تعني إنك مثلا عندك 1000 بيان في قاعدة البيانات و كلهم ليهم بيانات مرتبطة بالmaster records. فأنت لما تعوز تجيب البيانات المرتبطة دي بتعمل for loop كل مرة فيها الorm هايروح قاعدة البيانات من غير ما أنت تبقى واخد بالك، و كده أنت فشخت الperformance لما رحت 100 مرة + المرة الأولى اللي جبت فيها قائمة البيانات الأساسية.
و دي برضو الormm عامل لك ليها حل إنك تقدر تجيب البيانات الأساسية بالبيانات المرتبطة بيهم مرة واحدة، و ده بيسمى: eager loading

ثانيا: إيه هي المشاكل اللي بتحصل لما تستخدم الorms؟


* مشكلة رقم 1: سوء الاستخدام!!
- المبرمجين بيتستهلوا فبيعكوا في كتابة أكواد الاستعلام فبيطلع sql query زبالة، فبيأثر على الperformance!
و بسبب سوء الاستخدام ممكن تخبط في مشكلة n+1 اللي ذكرتها في التعليق السابق.
و بسبب سوء الاستخدام ممكن ما تنتبهش إن الorm بيعمل caching للobjects و تحتفظ باللsession لفترة طويلة أنت مش محتاجها (صدق أو لا تصدق: شفت برنامج بيحتاج 170 GB RAM عشان المبرمج كان بيحط الdbcontext في ال session بتاعت كل مستخدم!!!)
و ممكن نقول هنا بصفة عامة الكويريز اللي بتطلع من الOrms ما بتبقاش لطيفة!


* مشكلة رقم 2: التأثير السلبي على performance.عشان كده لازم تبقى فاهم الorm كويس عشان ما تعكش منك.
* مشكلة رقم 3: استخدامه في حالات هناك حلولا أفضل منها: مثال, إنك تستخدم الorm في التقارير، هنا مثلا أنت مش محتاج إن الorm يعمل caching للobjects و عاوزه يبقى سريع جدا، و الorm هايبطأ لك الدنيا

ثالثا: استدراكات لابد منها

1- كل نظام و له ظروفه، و الOrms لما طلعت - فيما أعلم - كانت عشان تحل مشاكل في الenterprise applications
و عشان كده لما موقع زي stackoverflow قابلته مشكلة في الperformance بقى إن الorm بوضعه الحالي مش مناسب، فعمل micro orm بيحل أول مشكلة ذكرتها فوق بس، فالنتيجة: لازال يستخدم صورة من صور الorm عشان توفر عليه شوية مجهود قد يكون كبير (حسب حجم النظام)
2- - لو أنت محتاج *بعض* وظائف الorms ما تعملهاش بنفسك، حتى لو بfunction صغيرة، عشان أنت كده بتعيد اختراع العجلة، خاصة لو فيه عجل كويس و هايسد معاك زي الmicro-orms!