يوميات مقالات تعليقات تعليقات خارجية
 
السلام عليكم، أهلا بك في صفحتي الشخصية... الساعة الآن 11:01 AM دقيقة بتوقيت الرياض
 
 

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

و الذي قمت به بإختصار عبارة عن عملية تغيير لكود التعبئة بحيث يقوم بإدخال الرسائل في جدول Outgoing_Emails على مراحل بإستخدام تقنية الـ Paging، و هي بشكل مختصر تعمل بالطريقة التالية:
يتم قراءة البريد الإلكتروني لأول 100 مشترك ثم اسجل رسائلهم في جدول Outgoing_Emails ثم انتقل للـ 100 مشترك الذين يتلونهم، و هكذا.....،، كل هذا يتم في جملة تكرار for-loop صغيرة....

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

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

و المشكلة بإختصار تكمن في الفنكوشة SendQueudEmail، حيث أنها تسمح بتنفيذ نفسها أكثر من مرة، و كان من المفترض ان لا أسمح بتنفيذ الفنكوشة SendQueueEmail في نفس الوقت أكثر من مرة، بكلام آخر كان يجب ان أجعلها Serialized Function، بحيث أنها عندما تبدأ في التنفيذ و تكتشف انه يوجد مسلك آخر Thread يقوم بتنفيذها يجب ان ترجع، و تؤجل تنفيذها، و هذه مشكلة تصنف في عرف المبرمجين ضمن أخطاءالتزامن Synchronization Bug، و من سيفهمه سيعرف لماذا يكرة المبرمجين برمجة التطبيقات المتعددة المسالك  Multithreading Application و يقولون أنها معقدة!.

المشكلة بإختصار حتى لا أصيبكم بالضجر هي ان الفنكوشة SendQueuedEmail ستسغرق في التنفيذ مدة طويلة بحيث أن المدة المحددة Interval في المؤقت Timer سوف تنقضي و يتم تنفيذ مسلك Thread  جديد لتنفيذ هذه الفنكوشة :).... بمعنى،، أن الفنكوشة SendQueuedEmail سوف يكون لها مسلكان thread يعملان في نفس الوقت لإرسال نفس الرسالة لنفس المشتركين، لأنني ببساطة أقوم بحذف الرسالة من جدول Outgoing_Email في نهاية الفنكوشة، و هذا الكود لا يتم تنفيذه إلا بعد إنشاء المسلك الجديد :) ....

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


و هذا هو الكود الجديد للفنكوشة بعد التعديل:

public enum Serialized
{
    Executing,
    NotExecuting
}
// متغير جديد لضبط التزامن
private static Serialized_sync = Serialized.NotExecuting;
public static void SendQueuedMail()
{
            string SmtpServer = EmailProvider.Instance().SmtpServer;
            string UserName = EmailProvider.Instance().UserName;
            string Password = EmailProvider.Instance().Password;
            int Port = EmailProvider.Instance().Port;
            EnumEmailFormat format1 = EmailProvider.Instance().EmailFormat;
            int emailPerCycle = EmailProvider.Instance().EmailsPerCycle;
            int maxAttempts = EmailProvider.Instance().EmailAttempts;
            ArrayList sentEmails = new ArrayList();
            ArrayList failedEmails = new ArrayList();
            
            if (_sync == Serialized.Executing)
                return;

            try
            {
                _sync = Serialized.Executing;
                // نفس كود الإرسال القديم                
               .....
            }
            finally
            {
                _sync = Serialized.NotExecuting;
            }
}


التعديل الذي في الأعلى بإختصار هو عملية فرض حصار على الدالة SendQueuedEmail بحيث لا يتنفذ منها نسختان في نفس الوقت،، بس!

موضوع آخر انتبته له مؤخرا وهو Bounce Email، فعندما قمت بإرسال أول رسالة بريدية للمشتركين في قائمة موقع ليه أنا استقبل بريد القائمة البريدية رسائل الإلكترونية كثيرة جدا لدرجة انها استحوذت على مايقارب 75 ميجا من مساحة البريد!....
كل هذه الرسائل بإختصار هي رسائل تسمى Bounce Email.

هذه الرسائل ترد من SMTP Server الخاص ببريد المستقبل، و هي تصنف إلى نوعين Soft Bounce و Hard Bounce، و يمكنهم الإستزادة حول الموضوع عن طريق قووقل Google لأنني حاليا ما زلت أبحث عن حل قليل التكلفة بدون شراء برنامج و لا إشتراك في خدمة مثل تلك التي يقدمها InboxResponse.com،،،

و في الختام أود ان أوجه أسفي العميق لثامر و للمشتركين في القائمة البريدية لموقع ليه أنا لأنهم وصلتهم رسائل مكررة من حلقة هذا الأسبوع (: .... أعذروني فهذه ضريبة الصناعة الوطنية ):

تحياتي للجميع،،،

نشر بتاريخ Thursday, February 01, 2007 3:23 PM

التعليقات

# re: هل لاحظ أحد هذا الخطاء البرمجي العنيف؟ أيمن 2/4/2007 12:35 PM

هلا أبومقحم ..

المشكلة أنك تتحدث عن جزيئة .. ونحن تنقصنا الفكرة الكاملة ..
وأنا ذكرت بعض الملاحظات في الرد السابق .. وربما كانت غير مواقة للواقع للسبب نفسه ..

المهم ..

مو لو استخدمت lock أحسن ..
انت رحت تسوي Handling لمشكلة التزامن .. وعندك أدوات جاهزة للتعامل مع المشكلة ..
وأنت اعرف مني بهالشي ..

تحياتي ،،،


# re: هل لاحظ أحد هذا الخطاء البرمجي العنيف؟ حُس حُس 2/4/2007 3:03 PM

المشكلة بسيطة جدا، وهي:
بعد مضي كل فترة يتم صنع مسلك thread لتشغيل SendQueueEmail و هذي الدالة تقوم بقراءة 50 رسالة مسجلة في الجدول Outgoing_Emails و ترسلها لأصحابها،،، و خلال عملية الإرسال يمكن ان تمر الفترة المحددة في المؤقت Timer و يتم إنشاء مسلك ثاني يقوم بمناداة SendQueueEmail مرة أخرى، بينقووو...
شفت المشكلة؟؟؟ لدنيا مسلكين يعملون في نفس الوقت، و يرسلون نفس الرسائل! لأن المسلك الأول لم يحذف الرسائل التي أرسلها بنجاح من جدول Outgoing_Emails...

لو قرأت الكود المنسوخ في الموضوع ستلاحظ انني عندما ارسل رسالة بنجاح، أقوم بوضعها في ArrayList، و في نهاية الدالة اقوم بحذف جميع الرسائل المسجلة في هذه ArrayList من جدول Outgoing_Email لأنها ببساطة أرسلت،،،،

أكره الحلول المعقدة!،، و على قولة Jeffery إذا كنت تستطيع ان تضبط نفسك بدون استخدام lock او سيمافور،،، فهذا أفضل! و هذا بالضبط ما قمت به... ضبطت عمل القائمة بدون استخدام lock ...

تحياتي،،،


# re: هل لاحظ أحد هذا الخطاء البرمجي العنيف؟ Mohannad 2/5/2007 1:24 AM

هذي القائمة أكيد جابت لك الجنان :)
الله يعينك عليها

تحياتي للجميع


# re: هل لاحظ أحد هذا الخطاء البرمجي العنيف؟ علي 2/10/2007 5:01 AM

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


العنوان  
الإسم  
الموقع
التعليق   
نص الصورة:
 • التصفح
 » RSS
 

 • المقالات

 » ASP.NET










 • الأرشيف





















 • اليوميات












 • الصور



جميع الحقوق محفوظة،
حسام المقحم 2006م