מאמרים בנושא ‏פיתוח‏.

טיפוסים דינאמיים או סטטיים?

ב־יום שני, 23 בינואר 2012, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים; ‏21 תגובות

נתקלתי בכתבה מעניינת

Static vs Dynamic Debate Decided

כל כך נכון. ככל שהפרויקט גדל ככה יותר קשה לעבוד עם שפות דינאמיות ובמיוחד לעשות refactoring אפילו פשוט לקוד.

מועמד לשחרור ראשון של הדור הבא של CppCMS זמין להורדה

ב־יום רביעי, 18 בינואר 2012, מאת ארתיום; פורסם תחת: תכנה חופשית, לינוקס, פיתוח, תכנה ומחשבים, CppCMS; ‏0 תגובות

אחרי פיתוח אינטנסיבי של כשנתיים וחצי, המועמד לשחרור של הדור הבא של CppCMS זמין להורדה.

איפשהו באפריל 2009 היה לי ברור שהארכיטקטורה של הדור הראשון של CppCMS לא הייתה מוצלחת:

  • ה־API היה בנוי בצורה שלא אפשר הרחבה קלה
  • הארכיטקטורה לא אפשרה פיתוח מונחה אירועים: Comet
  • הישענות על ספריות צג ג' כמו CgiCC ו־libfastcgi שהיו להן הבעיות API עמוקות, לא אפשרה לפרויקט להתקדם.
  • המערכת הייתה קשורה בצורה מאוד מובהקת ל־POSIX API ולא אפשרה תמיכה טבעית במערכת הפעלה Windows.

אחרי הרבה חשיבה, הבנתי שכדי לעשות קפיצת מדרגה משמעותית, צריך להתחיל לארגן את הקוד מחדש והתחלתי לעבוד.

העבודה הניבה פֵרות וביוני 2010 שחררתי גרסת בטא ראשונה. היא תפסה תאוצה באופן מידי. תוך חודשים ספורים כמות ההורדות קפצה מכ־100 הורדות בחודש לכ־300.

מהר מאוד, גרסת בטא הפכה לפופולרית. רוב משתמשי ה־CppCMS החלו לעבוד אתה או אפילו עם גרסת הפיתוח הזמינות דרך ה־svn. היום, רוב משתמשי CppCMS (אם לא כולם) עובדים עם גרסת פיתוח בטא. כל האתרים הפומביים שידוע לי עליהם, רצים על תשתית CppCMS החדשה.

למרות שבאופן רשמי, הדור הבא של CppCMS נחשב בטא, הוא היה יציב, מתוחזק היטב ובדוק הרבה יותר מהגרסה "היציבה", הסיבה היחידה שהוא היה נקרא "בטא" היא שאפשרתי לעצמי לשנות את ה־API בצורה לא תואמת, אחור, לזרוק API שהיה בנוי בצורה גרועה, לשנות סמנטיקה, לשפר ועוד.

היום, שנתיים וחצי אחרי שנוצר ענף "refactoring" ב־svn ה־API התייצב ומועמד לשחרור הראשון זמין להורדה.

על חשיבותן של בניות ובדיקות ליליות

ב־יום ראשון, 1 בינואר 2012, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים; ‏2 תגובות

לפני הרבה שנים כשעבדתי על פרויקטים שלי, לא התעסקתי יותר מידי בניהול בדיקות אוטומטיות. לפני שחרור גרסה הייתי מקמפל אותה על פלטפורמה אחת או שתיים (במקרה הטוב) והייתי משחרר.

זה גם עבד לא רע (בד"כ) - מקסימום הייתי משחרר תיקון או שניים אם מישהו היה מתלונן...

אבל כשהפרויקט מגיע ל־100,000 שורות של קוד, תומך במספר רב של מערכות הפעלה (Linux,‏ Solaris,‏ BDS,‏ Windows,‏ Darwin), מספר רב של קומפיילרים (gcc‏, clang‏, intel‏, msvc‏, sunstudio) ומספר רב של פלטפורמות (x86‏, x86_64‏, arm) אז הבדיקות ידניות לא ממש עומדות על הפרק, אלא אם כן, יש לך המון זמן=כסף מיותר.

אז מה צריך כדי להקל על ניהול הפרויקט?

  • בניות ליליות, כאשר המערכת נבנית כל לילה מאפס
  • בדיקות ליליות, כאשר בדיקות אוטומטיות מקיפות מתבצעות על כל פלטפורמה מידי לילה.

כמובן בניית מערכות בדיקות אוטומטיות זאת משימה לא פשוטה. צריך להכין טסטים פשוטים, מקיפים ומהירים לכל רכיב שיש במערכת, צריך להקים מערך של מערכות הפעלה וירטואליות ותסריט למעלה אותן מידי לילה. צריך רכיב שמייצר את הדו"ח הסופי, כך שמצד אחד יהיה קל לראות שהכול תקין, מצד שני קל לגשת לכל שגיאה ולהבין מה בדיוק קורה.

בניתי מערכת כזו עבור CppCMS וכל לילה נוצר לי הדו"ח הבא.

חייב להגיד, שלמרות כמות העבודה שהשקעתי בבניית המערכת הזו, אני מאוד מרוצה:

  • כבר הרבה פעמים זיהיתי באגים ובעיות בבדיקות שלא הייתי מגלה ללא מערכת כזו, כך למשל, אם תסתכלו בקישור היום (1/1/2012) אז תגלו שרוב הטסטים נפלו, לא נעים לגלות שלא עשיתי בדיקה מספיק טובה לפני commit, אבל אחרת לא יודע מתי הייתי מוצא את הבעיה.
  • בניה בעזרת מספר קומפיילרים בודקת בצורה טובה את הקוד: עד כמה הוא קוד תקני, בנוסף היא מאפשרת לראות מספר לא מבוטל של הערות שונות של קומפיילרים שונים שלעתים מעידות על בעיות בקוד שלמשל gcc לא מזהה.
  • זה מאוד מקל על תהליך שחרור הגרסה. כל מה שצריך לעשות:

    1. להתעורר בבוקר ולוודא שכל הטסטים עברו
    2. להריץ תסריט שייצור גרסה מוכנה ולהעלות אותה ל-SF.‏
    3. לפרסם הודעה בבלוג/ברשימת תפוצה.

אז אם אתם מנהלים פרויקט תוכנה (לאו דווקא קוד פתוח) תקפידו לעשות בדיקות ליליות. שימו לב: לא רק בניות אלא גם בדיקות.

מפתח בארץ ה־IDE

ב־יום חמישי, 29 בדצמבר 2011, מאת ארתיום; פורסם תחת: תכנה חופשית, לינוקס, פיתוח, תכנה ומחשבים, C++‎‏; ‏8 תגובות

לאחרונה, הייתי צריך לבחון סביבת פיתוח משולבת (IDE) בלינוקס, ולעשות להן השוואה: איזו סביבה היא יותר מתקדמת ונוחה בהקשר של פיתוח ב־C++‎. למרות שאני כותב הרבה קוד, ויצא לי בעבר להשתמש בלא מעט IDE, ביניהם גם Visual Studio וגם KDevelop 3, אני מעדיף לעבוד עם vim, סביבת הפיתוח האולטימטיבית. אבל vim בתור "סביבת פיתוח משולבת" זה לא בדיוק מוכר. יש אנשים שאוהבים IDE... כך שפשטתי שרוולים והתחלתי לבדוק.

על הפרק עמדו מספר אופציות:

  • KDevelop שהיה לי ניסיון איתו בגסראות 3
  • Eclipse שרבים עובדים איתו
  • Netbeans שרבים ממליצים עליו

ומספר IDE נוספים: Anjuta, CodeBlocks ו־CodeLite.

התחלתי מ־KDevelop 4:

בעבר היה לי ניסיון לא רע עם KDevelop 3 והחלטתי לתת לסביבה הזו הזדמנות נוספת. לפני שאני מתחיל את הסיפור, אומר, אחרי כ־20 דקות עבודה התחלתי להרגיש שאני יותר פרודוקטיבי עם KDevelop מאשר עם vim!

הסביבה עשתה צעד עצום מאז גרסה 3. השלמה אוטומטית כמעט מושלמת ומהירה, highlighting מעולה וגם tooltips מאוד נוחים שמאפשרים לגשת לכל מקום. שילוב נוח עם CMake, הגדרות פשוטות, התנהגות ברורה, אינטגרציה עם קובצי man ועוד.

התחלתי לממש פיצ'ר מסוים עבור cppdb‏ ולראשונה הרגשתי שאני מצליח לכתוב קוד מהר יותר ומדויק יותר בהשוואה ל־vim.

הסביבה מאוד מהירה ומגיבה בצורה כמעט מידית.

מבחינת יכולת הדיבוג, הדבר היחיד שלא הצלחתי למצוא זה כיצד אני מגדיד למשל catch throw - לעצור על זריקת החריגה, בסוף, הפעלתי את זה ישירות דרך מסוף ה־gdb.

יחד עם כל היתרונות האלה, היא באה עם חסרון אחד גדול ובלתי נסלח: היא קורסת מידי פעם. תוך כדי העבודה היא עפה לי מספר פעמים. אומנם, לא איבדתי שום דבר, פתחתי אותה מחדש ותוך מספר שניות חזרתי לעבוד בדיוק מאותו מקום, עדיין, בעיניי זה משהו שלא אמור לקרות, נקודה. סימן קריאה!

המשכתי ל־Eclipse

אחרי מעט הגדרות הצלחתי לגרום לו לעבוד עם קובץ Makefile הנוצר ע"י CMake, הגדרתי פרויקט והתחלתי לעבוד.

הסביבה עבדה בצורה יפה, לא הרגשתי אטיות מיוחדת, יחד עם זאת, היא לא הגיבה בצורה מספיק מהירה בעיניי. כשהקלדתי foo.‎ - אחרי הקלדת הנקודה יש השהיה קטנה עד שהתפריט מופיע. אומנם היא מאוד קצרה, היא עושה הבדל מהותי במהירות הכתיבה שלי.

בנוסף, בניגוד ל־KDevelop הוא לא ידע להשלים ערכים תוך כדי הקלדה בצורה לגמרי אוטומטית, למשל אני מתחיל לכתוב my_variable הוא לא מציע לי השלמה אחרי שכתבתי my_va - צריך ללחוץ ctrl-space, אבל בסה"כ הסביבה בהחלט לא רעה ופרודוקטיבית.

התרשמתי לטובה מסימון השגיאות בקוד תוך כדי כתיבה, הוא הרגיש לי קצת יותר ברור בהשוואה ל־KDevelop, מבחינת הדיבוג המצב היה דומה לזה של KDevelop.

בכל אופן, הרגשתי שזאת סביבה ברמה מאוד גבוהה, אבל קצת אטית.

ניסיתי סביבות "קלות" יותר

אז פתחתי CodeBlocks שרבים ממליצים עליו. ויתרתי עליו די מהר - מבחינתי חוסר אינטגרציה עם כלי בניה חיצוניים הוא "deal-breaker" ובכלל לא התרשמתי ממנה יותר מידי. ניסיתי קצת codelite - גם הוא היה יותר מידי lite לטעמי.

לאחר מכן ניסיתי Anjuta, שגם אתה עבדתי בעבר. לא התרשמתי יותר מידי. בפרט, למשל חסרה אפשרות להשלמת הפונקציות של מצביעים חכמים ועוד.

גם היא ירדה מהפרק די מהר.

נותרה לי סביבת Netbeans

שמעתי עליה הרבה דברים טובים והמלצות רבות. בעבר יצא לי לנסות אותה אבל ויתרתי עליה כמעט באופן מידי, אחרי שיא המשיכה "ליצור אינדקס" של הפרויקט במשך דקות ארוכות. אבל החלטתי לתת לה סיכוי במחשב החדש.

בניגוד לסביבות אחרות שזמינות ישירות ומהמאגרים של Ubuntu, ‏Netbeans לא מופיעה שם, צריך להתקין אותה בנפרד. הורדתי את הגרסה היציבה האחרונה המותאמת לפיתוח C++‎ והתקנתי.

פה הייתה לי הפתעה ממש טובה:

  • אפילו שהיא צרכת הרבה יותר זיכרון מ־eclipse ו־KDevelop הסביבה עבדה מאוד מהר, השלמה אוטומטית כמעט מושלמת ומהירה.
  • אינטגרציה מעולה עם subversion, למשל הצגת diff מאוד נוחה עם אפשרות עריכה ישירה.
  • הגדרות פשוטות
  • אינטגרציה עם CMake (שחסרה ל־eclipse)
  • תפריטים נוחים והגיוניים (ב־eclipse הן היו ממש קטסטרופה)

ועוד

ובכלל, הרגשתי שזאת סביבה מאוד פרודוקטיבית, בנויה היטב ויעילה. מה שכן, היא ללא ספק בנויה למחשבים חזקים עם כמויות זיכרון גדולות.

סיכום

אחרי הרבה שנים של עבודה עם vim אני חושב שאתחיל לבחון את הגישה שלי ל־IDE מחדש. כרגע Netbeans היא הבחירה המובילה. הייתי מאוד רוצה לעבוד עם KDevelop אבל אני לא חושב שאוכל לעבוד אתו כל עוד הוא קורס.

מבחינתי יציבות ואמינות יותר חשובה מכל פיצ'ר אחר, וכרגע KDevelop לא עונה על הדרישה הבסיסית הזו וחבל.

Sqlite - עבודה עם WAL.

ב־יום ראשון, 4 בדצמבר 2011, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים; ‏0 תגובות

אומנם גרסה 3.7 של Sqlite שוחררה יותר מלפני שנה, לא רבים שמו לב לשורה הקצרה ברשימת השינויים:

Added support for write-ahead logging.‎

זאת שיטת עבודה שכל בסיס נתונים מודרני עובד איתה, לעומת שיטת העבודה הרגילה של Sqlite3 והיא ניהול "לוג לשחזור לאחור" - Rollback.

כיצד קובץ Rollback עובד. בכל פעם שרוצים לעשות שינויים בדף של קובץ בסיס הנתונים, רושמים את הערכים בקודמים בקובץ במיוחד. כך שאם ניפול, נדע בדיוק איך לשחזר את המצב הקודם. אז בכל טרנזקציה Sqlite3 מבצע את הפעולות הבאות: רושם את הכל המחיקות לקובץ rollback ומבצע fsync עליו, לאחר מכן מעדכן את בסיס הנתונים הראשי ומוודא כי הנתונים הגיעו לדיסק עם fsync נוסף ובסוף מוחק את קובץ ה־rollback. מה שחשוב כאן זה שקריאת מערכת הפעלה fsync, מתבצעת פעמיים: פעם על קובץ לוג ופעם על הקובץ הראשי. הקריאה הזו מבטיחה שהמידע הגיע לדיסק פיזי והיא כמובן מאוד יקרה מבחינת הזמן.

השיטה החדשה שמומשה בגרסה 3.7, עובדת עם קובץ WAL -‏ Write Ahead Log. כל שינוי נרשם לקובץ הלוג והקובץ המקורי נשמר ללא שינויים. מה שחשוב כאן שכדי להבטיח שרידות מספיק לקרוא fsync - פעם אחת בלבד עבור קובץ WAL. הטרנזקציות הבאות יוסיפו עוד מידע לסוף הקובץ. אחת לכמה זמן sqlite3 מעביר את כל השינויים לקובץ בסיס הנתונים המקורי ומאפס את קובץ הלוג. יותר מזה, כיוון שהקובץ המקורי נשאר ללא שינויים אז טרנזקציות קריאה יכולות לרוץ במקביל לטרנזקציות כתיבה.

השיטה החדש מבטיחה מהירות ביצוע טרנזקציה גבוהה יותר בגלל ש־fsync נקרא רק פעם אחת. בנוסף וגם עדכונים לא מעכבים את טרנזקציות השליפה.

כך שאם אתם משתמשים פעילים של Sqlite3 - תבדקו את האופציה

PRAGMA journal_mode=WAL;

היא יכול לשפר משמעותית את היישומים שלכם.

בנוסף עם תמיכה ב־WAL, התווספה עוד אופציה מעניינת שמאפשרת להאיץ פעולות עדכון של בסיס נתונים בצורה משמעותית בלי לפגוע בקונסיסטינטיות שלו. כלומר לוותר על ה־D של ACID.

אם מגדירים

PARAGMA synchronous=NORMAL

אז במצב של WAL ה־fsyncים שמבטיחים את ה־D -‏ Durability ייקראו רק פעם ב־checkpoint ולא כל טרזקציה. אם המחשב קורס (חשמל/חומרה) אז אנחנו נאבד מספר טרנזקציות אחרונות אבל בסיס הנתונים יישאר תקין, במילים אחרות, אנחנו ניפול בגבול טרנזקציה, אבל לאו דווקא הטרנזקציה האחרונה. שיטה זו מאפשר להגדיל מספר עדכונים מכמה עשרות בשנייה לכמה אלפים.

גם חלק מבסיסי הנתונים הגדולים תומכים באפשרות העבודה ב־ACI ללא D.

למשל, ב־PostgreSQL ניתן להגדיר אופציה synchonous_commits=off ברמת הקשר. אז עדכון הלוג יתבצע ללא fsync ורק פעם בשניה יתבצע עדכון מלא. בבסיס הנתונים MySQL אפשר להגדיר את זה בעזרת אופציה innodb_flush_log_at_trx_commit=2, אבל ההגדרה הזו תעבוד ברמת שרת MySQL כולו ולא רק ברמת הקשר או בסיס הנתונים הספציפי.

שימוש באופציות כאלה מאוד משפר ביצועי העדכונים. אפשר וכדאי להשתמש בהן כשיש חשיבות לטרנזקטיביות, אבל זה ממש לא קריטי לאבד מספר טרנזקציות אחרונות במקרה של קריסה.

העמוד הבא

העמוד הבא

דפים

נושאים