בחרנו ב-Monorepo ואז החלו האתגרים. כך פתרנו אותם

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

בחירת דרך ניהול הקוד משפיעה באופן דרמטי על תהליכי הפיתוח בחברה (צילום: Dreamstime)

מאת לינוי שקורי, R&D Team Leader ב-JUSTT

אחת ההחלטות שחברות תוכנה צריכות לקבל עם צמיחת ספריית הקוד היא היכן לנהל אותו. האם כדאי לעשות זאת ב-Git Repository אחד? בכמה נפרדים? או שבכלל עדיף להקים Repository עבור כל שירות, תשתית וחבילת קוד שנכתבים בחברה? ורגע, אולי הדרך הנכונה היא בכלל ב-Git Repository בתצורת Monorepo?

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

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

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

  • ריכוז הקוד במקום אחד – מקור אמת אחד מקל על מעקב אחר שינויים ועל התמצאות בקוד. זה חשוב במיוחד אצל חברות בתחילת הדרך, שבהן התוכנה משתנה ומתפתחת בקצב מהיר ומפתחים חדשים מצטרפים בתדירות גבוהה.
  • שיתוף קוד בין צוותים בארגון ושימוש חוזר בקוד – זה מטשטש את גבולות האחריות של צוותי הפיתוח השונים ואת הגדרת הבעלות על קוד – דבר חיובי לרוב הדעות.
  • תמיכה בשינויים אטומיים – PRי(Pull Request) אחד שווה משימת פיתוח שלמה. זה מאפשר שיתוף פשוט עם מפתחים אחרים ומקל על ביטול שינויים במקרה הצורך.
  • אינטגרציה רציפה (Continuous Integration) – במונוריפו, כל PR שנכנס הוא כמו שחרור של גרסה מלאה. לעומת זאת, כאשר עובדים במספר Repositories, בכל פעם שנרצה להריץ את המערכת בשלמותה נצטרך לבצע אינטגרציה קצרה (במקרה הטוב) של כל החלקים – עוד נקודת כשל פוטנציאלית.

אלכס איגל ניסח זאת היטב בטור לאתר "Medium":י"If you don’t have a monorepo, you’re not really doing continuous integration, you’re doing frequent integration at best".י

הקוד גדל, מפתחים הצטרפו – ואז האתגרים התגלו

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

1. PR race conditions/Merge wars

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

איך התגברנו על הבעיה? פשוט הכנסנו את ה-PR לתור. הטמענו מוצר צד שלישי בשם MergeQueue שתפקידו לנהל תור של PRs. בדרך זו מפתחת יכולה להפסיק לנטר את ה-PR שלה ולדעת שברגע שיגיע תורו, הקוד ייכנס ללא התערבות מצדה. השימוש בתור חוסך גם את הזמן של המפתחים (שצריכים לנטר את ה-PR, לחכות שה-CI יסיים לרוץ ולעדכן את הקוד כל הזמן), וגם את כל ריצות ה-CI המיותרות – ובכך חוסך זמן וכסף עבור סביבות ההרצה של ה-CI. בנוסף, תור נותן לנו יכולת לנהל עדיפות, כך שכאשר יש תיקון שחייב להיכנס מיידית, זה יקרה מבלי לפגוע בשאר ה-PRs הקיימים (אגב, ישנם פרויקטי קוד פתוח נוספים עם יכולות דומות, כגון kodiak).

בתמונה ניתן לראות את ההשפעה של MergeQueue על ניצול משאבי ה-CI שלנו. בירוק – כמות ההרצות הזמינה, ובצהוב – הניצול בפועל.

2. תהליך בנייה שהולך ומתארך

בתהליך הבנייה ההתחלתי שלנו ב-CI כל השירותים נבנו מחדש בכל פעם, והוא הלך והתארך ככל שהקוד התרחב וככל שנוספו עוד ועוד שירותים (בתוך שנה הגענו ליותר מ-100 שירותים). זה הפך להיות גורם מעכב בתהליך הפיתוח – בזבוז של זמן יקר וכסף עבור סביבות ההרצה והאחסון של התוצרים.

איך התגברנו על הבעיה? הטמענו כלי בשם Nx שתפקידו לבנות ולבדוק בצורה יעילה רק שירותים שהושפעו מהשינויים ב-PR, ומשתמש בתוצרים שנבנו מבעוד מועד עבור השירותים שלא הושפעו מהשינוי. לאחר ההטמעה של הכלי, זמן הריצה של ה-CI ירד ב-62%.

בנוסף, לכלי יש יכולת לחולל (Generate) שירותים מתוך תבניות ניתנות לשינוי, ולקצר משמעותית את הזמן שלוקח ליצור שירות חדש.

3. ניטור תהליך הפיתוח ושיפור מתמיד

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

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

איך עשינו את זה? בשוק קיימים היום כמה כלים לניטור תהליכי פיתוח, בחלקם ניתן להשתמש בחינם. אנחנו משתמשים בכלי שנקרא LinearB, שלו אינטגרציה מובנית עם GitHub וג'ירה והוא מציג מטריקות מוגדרות מראש בנוגע לתהליך הפיתוח. וכמובן, אפשר להשתמש בתוכנת ניהול משימות (כגון ג'ירה) כדי לנטר בעצמנו חלק מהשלבים.

בתמונה ניתן לראות דוגמה לניתוח Cycle-time מהאתר של LinearB. מטריקה זו מודדת כמה זמן לוקח לפתח משימה אחת מקצה לקצה – מהרגע שמפתח התחיל לעבוד על המשימה ועד שהיא הגיעה לסביבת ייצור.

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

הכתבה בחסות JUSTT

ג'אסט היא חברת פינטק שהופכת את המחלוקת בכרטיסי אשראי על הכחשת עסקאות לתהליך הוגן, פשוט ונטול מאמץ לבעלי עסקים. החברה משתמשת בלמידת מכונה ובמומחיות מעמיקה בתחום כדי לספק פתרון מותאם אישית ומתוחכם, המטפל בהונאות חיוב חוזר באשראי, עם אחוזי הצלחה גבוהים, תוך ביטול הצורך של הלקוח להשתמש במשאבים פנימיים. ג'אסט נוסדה ב-2020. כיום יש לה מעל 180 עובדים ועובדות, והיא גייסה 70 מיליון דולר. ב-2021, לינקדאין דירגה את ג'אסט כאחד מ-15 הסטארטאפים המובילים בישראל, במונחים של השקעות וצמיחת עובדים

כתבת אורחת

הגב

4 תגובות על "בחרנו ב-Monorepo ואז החלו האתגרים. כך פתרנו אותם"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.

סידור לפי:   חדש | ישן | הכי מדורגים
יוניטי מן
Guest

סוף סוף כתבה עם תוכנת רלוונטי! תודה רבה על המידע :)

בעל הצבתות הצהוב
Guest
בעל הצבתות הצהוב

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

Bell
Guest

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

ערן
Guest

אם למדתם מגוגל על מונוריפו, למה שלא תלמדו מהם איך לפתור את שאר הבעיות שתוארו? ;)

wpDiscuz

תגיות לכתבה: