Artwork

תוכן מסופק על ידי רברס עם פלטפורמה. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי רברס עם פלטפורמה או שותף פלטפורמת הפודקאסט שלו. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.
Player FM - אפליקציית פודקאסט
התחל במצב לא מקוון עם האפליקציה Player FM !

435 Optibus Playback with Eitan Yanovsky

 
שתפו
 

Manage episode 322741079 series 2497397
תוכן מסופק על ידי רברס עם פלטפורמה. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי רברס עם פלטפורמה או שותף פלטפורמת הפודקאסט שלו. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.

היום אנחנו מארחים באולפן בכרכור את איתן ינובסקי בשנית: איתן התארח בפודקאסט ב-2018 (Before Covid), אז דיברנו על כמה אתגרים טכנולוגיים מעניינים שיש בהחברה שלו - Optibus - והיום נדבר על עוד אתגרים.

ולפני שנצלול לאתגרים, איתן - ספר לנו קצת על עצמך ועל Optibus
  • (איתן) אז אני איתן, ה-CTO וה-Co-founder של Optibus; עוד רגע נושק לגיל 40, עבר זמן . . .
  • אנחנו בונים פלטרפורמה לתכנון וניהול של תחבורה ציבורית ושל הסעות המונים, שממש אחראית על תכנון של איך אנחנו הולכים להסיע מיליונים של אנשים ברחבי העולם.
    • היום, בפועל, אנחנו פרושים כבר בלמעלה מ-30 מדינות ומתעסקים בהסעות של 2.5 מיליארד אנשים, ברמה שנתית.
(אורי) פתאום, כשאתה מדבר על זה - כאילו בא לי לשאול אותך על הקורונה, אבל זה נראה לי . . . . היא עשתה לכם משהו בימים האלה, כשהתחבורה הציבורית הפסיקה?
  • (איתן) אז זו באמת שאלה מעניינת - כשהתחילה הקורונה אז כמו לכולם היו לנו קצת חששות, בפרט לגבי תחבורה ציבורית, אבל . . .
(רן) היא לא הפסיקה, רק השתנתה . . . זה באמת אתגר מאוד גדול למי שמתכנן . . . .
  • (איתן) בדיוק, כי במקום להפסיק . . . היו שבועות שזה ממש הפסיק, נגיד בסגר המוחלט בישראל, אבל אז זה הפך לגלים של “עכשיו אנחנו צריכים 50% או 20% או 80%”, ברמה ממש שבועית, וזה משתנה.
    • זה דווקא עשה אפקט הפוך - שפתאום הרגישו את הצורך במערכת כמו שלנו,
      • במקומות שהשינויים הם יחסית איטיים - פעם בחצי שנה או שנה - ועכשיו אני צריך פתאום להגיב לדרישות של שינויים ברמה השבועית . . . .
(רן) ניתן רק בשתי מילים, למי שלא זוכר את תקציר הפרק הקודם - בגדול, במקום לעבוד עם טבלה ונייר שבהם רושמים מי נוהג באיזה אוטובוס ואיזה קו הוא עושה, אז Optibus מתכננת את כל זה, ועוד הרבה יותר, מן הסתם - אבל עושה את זה באופן אוטומטי ויעיל. כך שתכנון לוחות הסעות וכל מה שקשור בזה - אם זה משתנה ברמה יומית אז זה כבר לא פרקטי לעשות בידי אדם, אבל Optibus יודעת לעשות את זה.
  • (איתן) נכון, ומאז גם התרחבנו הרבה יותר במה שאנחנו עושים, מרמת תכנון הרשת ואיך שזה מגיב לביקושים והלוחות זמנים
    • רכבים, נהגים . . . ברמה של תפעול יומיומי ואיך להגיב למה שקורה ביומיום וכו’.
    • דווקא בקורונה פתאום נוצר צורך הרבה יותר גדול במערכת - דווקא הייתה לנו את אחת השנים הטובות, שלאחריה הגיע גם ה-Round C שעשינו.
    • היום אנחנו Post Round C
  • היום אנחנו כבר באיזור ה-330 אנשים - אני חושב שבפעם האחרונה שדיברנו היינו באיזור ה-50-60, אני לא זוכר בדיוק את המספרים
  • ובסופו של דבר, כמו שאמרתי, אנחנו מסיעים מיליונים רבים בעולם - הלקוחות שלנו משתמשים במערכת כדי לתכנן איך להסיע את האנשים הללו בצורה מיטבית.
(רן) אז הלקוחות זה חברות אוטובוסים דוגמת “אגד”, לא יודע אם כלקוח ספציפית שלכם אבל כדוגמתם, בעולם . . .
  • (איתן) נכון, אגד הם לקוח ספציפי שלנו, אפילו אחד הראשונים, אבל כן - חברות כאלו בעולם.
    • בנוסף - לא רק: גם חברות שבעצם . . . למשל בניו-יורק יש חברות שהן חצי-ממשלתיות שאחראיות על התחבורה
    • אבל גם חברות כמו Facebook ו-Apple שהן לקוחות שלנו, ל-Commute של ה-Employees’ Shuttle שלהם
    • זה צי של מאות אוטובוסים שיש להם שם.
  • אז בעצם כל התעסקות במסות גדולות של אנשים, שצריך לתכנן את זה מראש ולא רק להגיב on-the-fly -
    • כי אתה צריך לבנות רשת שתיהיה יעילה, אחרת התפעול יהיה מאוד לא יעיל.
(רן) מבחינת התפעול, לא הביצוע - הנהגים הם לא הנהגים שלכם, האוטובוסים לא שלכם . . . .
  • (איתן) נכון, אנחנו רק SaaS ו-Everything is on the Could - אנחנו לא מספקים שירותים מעבר לזה.

(רן) כשעשינו את ההכנה לפודקאסט, ראינו שאחד האתגרים שצצים זה ש”אוקיי, אז מה קורה אם הוספתי פיצ’ר - תיקנתי באג, אני חושב שתיקנתי באג ואני לא רוצה שאותם 2 מיליארדים שמחר נוסעים בבוקר פתאום ימצאו את עצמם בלי אוטובוס . . . . “.
אז איך עושים QA למערכת שכזו?
  • (איתן) בעצם אנחנו Mission Critical SaaS system, והמשמעות של רגרסיות - ה-Impact של זה בסוף משפיע על התפעול של התחבורה וגם יכול להגיע למצב שאי אפשר להוציא למחרת את התחבורה, או אפילו ב-Day-to-Day . . .
(אורי) עכשיו אתה חייב לתת דוגמא לבאג ומה שקרה . . . .
(רן) “אז כשעברנו מהמערכת המטרית למערכת של המיילים, כל האוטובוסים עצרו שישה מייל לפני התחנה” . . . . [How NASA lost a 327 Million Dollar Mission to Mars]
  • (איתן) השוליים צרים מלהכיל את כל הבאגים שקרו לנו ואת הפאדיחות . . .
  • אבל אתה יודע - יש את הרגעים האלה שמכניסים משהו וזה מקריס את ה-Production פתאום, וככל . . .
    • בהתחלה, נגיד כשזה היה קורה לנו לפני חמש שנים, ה-Usage במערכת לא היה כזה גבוה ולפעמים היה לוקח אפילו 20 דקות עד שמישהו שם לב.
    • עכשיו זה תוך שלוש שניות - ה-Support מתחיל להפציץ אותנו בדברים שלא עובדים, אז אתה מבין את ה-Impact של כל . . .
(אורי) כי מתקשרים אליהם?
  • (איתן) גם יש Monitoring וגם כן - ה-Support שמתקשרים אלינו.
    • בסוף ה-User-ים של המערכת שלהם, זה מה שהם עושים ב-Day-to-Day - נכנסים לעבודה, פותחים Log-in ל-Optibus ומתחילים לעבוד
    • ואם משהו לא עובד אז . . .
(אורי) וזה “הסדרנים”?
  • (איתן) זה מתחיל מאנשים שמתכננים את רשת הקווים, עובד לאנשים שאחראים על שיבוץ תוכנית הרכבים והנהגים ובסוף . . . .
  • הסדרנים זה יותר ה-Day-to-Day - עכשיו אני צריך לתפעל את מה שקורה
  • ויש גם את האפיק של התכנון - מה עושים מחר ובעוד שבוע ובעוד חודש?
    • איך אני מגיב ל-FIFA, למשל - יש אירוע לתכנן . . . .
    • משתמשים בנו כדי לתכנן לקראת אירועי ספורט כמו אליפויות עולם וכו’.
    • אז כן - משתמשים מהסוג הזה.
  • הסדרן - זה כמובן הכי קריטי מבחינתו, כי הוא ממש עכשיו מטפל ברכבים שנמצאים על הכביש וצריך להתמודד עם מה שקורה שם, וכשהולכים שנה אחורה זה ניהיה . . .
(אורי) אז רק כדי שנקבל את הסדר-גדול של מה שקורה כשיש באג משמעותי . . . .
  • (איתן) תחשוב על זה ש-60% מהתחבורה באנגליה מתוכננת באמצעות המערכת שלנו . . . אם הכנסנו משהו שבאמת, לצורך העניין, כל כך משמעותי שהוא באמת Crippling של כל המערכת, אז למחרת - או כרגע, תלוי באיזה רכיב אתה מקלקל במערכת - זה יכול ממש לדפוק את ה-60% . . . לגרום לבעיה בתחבורה, ש-60% מהנסועה . . .
  • (איתן) כן . . . .לא הגענו לסיטואציה כזו אף פעם, בדרך כלל אם אני אתקע אז זה על דברים של עוד כמה ימים, לא ממש ב-Real-time, זה קטסטרופלי.
    • אבל כן - צריך לדאוג שזה לא יקרה, ומן הסתם היו הרבה Crisis-ים ובכל פעם השתפרנו ובנינו דברים ויכולות כדי למנוע ושזה לא יקרה יותר, דברים כאלה.

(רן) אז כמו שאתה אומר, יש פה שילוב של מערכת SaaS, זאת אומרת שזה Software as a Service וזה לא שאתה שולח דיסקים לחברת האוטובוסים - זה הכל נמצא שם בענן ואתה יכול לעדכן את זה בכל דקה, ואני מניח ש-Continuous Deployment זה כבר “חדשות דאשתקד”, מצד אחד. מצד שני, כמו שאמרת זה Mission Critical, וזה אומר שיש אנשים שתלויים באופן קריטי בזה שהמערכת תפעל - ותפעל נכון, לא רק תפעל . . .
  • (איתן) נכון, ועוד דבר שמאפיין זה שאין הרבה משתמשים שונים במערכת
    • זה לא, נגיד, Facebook - כשיש לך עשרות מיליוני משתמשים ואתה יכול, אולי, לעשות נזק לאחוז מסויים.
    • מעבר לזה ש-Facebook הוא לא Mission Critical . . . אולי אפשר להתווכח על זה עם כל מיני אנשים, אבל במציאות . . . .
(רן) תלוי במשטר . . .
  • (איתן) תלוי במשטר . . . יחסית יותר קל להגיד “אוקיי, בואו נפרוש משהו לאחוז אחד מהאוכלוסיה”.
  • אצלנו, בסוף המשתמשים זה לא הנוסעים אלה אנשים האנשים שמתכננים את התחבורה.
    • אז זה מאות משתמשים - גג - בו-זמנית, ואחוז אחד זה כבר לא מספר Significant-י לעשות שום דבר
    • מעבר לזה - אפילו אם תדפוק לאחוז האחד הזה משהו שהוא קריטי, זה עדיין עלול לייצר בעיה במקום כמו אם האחוז הזה עכשיו אחראי על התחבורה בלונדון או משהו כזה, ואז אתה מייצר שם נזק.
(רן) אני חושב, דרך אגב, אם אני לא טועה, ב-Waze הם אמרו שישראל זה כר-הניסוי שלהם . . . . סוג-של, כן - לא נוציא את הדברים מהקשרם [הנה הקשרם - 419 Navigation @Waze], אבל שפיצ’רים חדשים יוצאים קודם כל במדינה מסויימת, שיודעים ששם יש יותר רצון לקבל חדשנות, ורק אחר כך מעבירים את זה לשאר העולם.
זה משהו שאתם עושים גם?
  • (איתן) אז אנחנו במתח . . . . עכשיו, ממש לאחרונה, התחלנו והוספנו מערכת של Gradual Rollout.
  • בנינו אותה In-house, כי ה-Gradual Rollout של היום יותר בנוי ל-Use-case הזה, כמו שאמרתי, של Facebook - כשיש לך סגמנטציה ומלא משתמשים - ופחות למקרה שאני רוצה, ללקוח Enterprise מסויים, שהוא יהיה ב-Stage X ב-Deployment, כי אני יודע שהוא פחות Tolerant לבעיות.
    • ואנחנו באמת פורשים בשלבים - כאשר אתה מתחיל יותר עם ה-Early Adapters - שאתה גם מסכם איתם שהם יחשפו ראשונים והם רוצים לקבל את הדברים כמה שיותר מהר
    • ומגדילים את החשיפה כשאנחנו פוגשים, נגיד, את ה-Enterprise, טיפה יותר מאוחר - וגם אצלם מחליטים מי יהיה ה-Early Adapter בתוך ה-Enterprise, כי אנחנו יודעים גם בתוכו לעשות את ה-Gradual Rollout.
  • וזה ממש משהו שהכנסנו, יחסית, בחצי שנה האחרונה - וממשיכים לשפר ולנטר את זה.

(רן) אוקיי, אז אלו פתרונות יחסית מוצריים, או “Biz-Dev-יים” נקרא לזה - אבל בוא נדבר רגע על פתרונות טכנולוגיים.
הקמתם, בעצם, מערכת פנימית שקראתם לה . . . .
(רן) אז בוא - ספר לנו עליה.
  • (איתן) אז אני אספר רגע על המוטיבציה - אנחנו מאמינים מאוד ב-TDD, הרבה Coverage בטסטים
    • אבל בסופו של דבר אתה עדיין מוצא את עצמך עם רגרסיות ב-Production ו-Crisis-ים . . .
    • והתחלנו לתחקר למה זה קורה.
  • עברנו ממש על . . . אמרנו “בואו נסתכל על השלושה חודשים האחרונים”, על כל הבאגים שהוגדרו כ-On-call, זאת אומרת שהגיעו ב-Production ויצרו Stop the work וצריך עכשיו לתקן אותם . . . .
(אורי) אז זה קרה כי הרגשתם שיש תקופה שבה זה קורה יותר?
  • (איתן) כן - וגם כי כמות ה-User-ים שלנו גדלה פי-2 כל שנה - אז כשיש לך 5-10 User-ים ה-On-call פחות חווה את המשמעות של שלושה אנשים שמתקשרים.
    • כשפתאום 50 אנשים מתקשרים שהם לא מצליחים לעבוד, ואז 100 אנשים בו-זמנית - אז גם העוצמה של ה-On-call הופכת להיות . . . .
    • בעצם, ההגדרה של ה-On-call לא הייתה קיימת בשנתיים-שלוש הראשונות שלנו - זה התחיל רק כשבאמת הגענו למצב שאתה אומר . . . On-call אומר שמישהו צריך לעצור ולהסתכל על זה, כי זה מונע ממישהו לעשות את העבודה שלו, או יותר ממישהו (אחד)
      • אבל אפילו מישהו אחד אצלנו זה מספיק.
  • עשינו תחקור, ראינו שהיו קצת Crisis-ים, ראינו שזה קרה יותר מדי ואמרנו “בואו ננסה להבין למה”.
    • אנחנו עובדים Data-Driven בחשיבה.
(רן) אז אמרתם ללקוח “אבל הכל טסטים ירוקים! מה אתה רוצה ממני?”
(אורי) אצלי זה עובד!”
  • (איתן) בדיוק . . . .
  • אז ממש עשינו קטיגוריות לסיבות של למה זה קרה - לפעמים זה Missing Test, לפעמים זה ש-QA שפספס, לפעמים זה . . . לא יודע, סתם “צעירות”, נקרא לזה.
  • אבל ראינו שאחת מהסיבות שחוזרות על עצמן זה . . . .
(אורי) “QA פספס” זו הסיבה הכי . . . . זה ה”עלה תאנה” הכי גדול שיש
  • (איתן) זה גם מעט מאוד ממה שאתה מחשיב, מהסיבות . . . .
(אורי) כן, אבל כאילו . . . .
(רן) אורי אומר שכשיש ש.ג. שמולו עומד טנק - ואם הוא נותן לו להכנס אז אתה אומר “פאשלה של הש.ג.!” . . . .
  • (איתן) נכון, אז כשאמרנו “QA שפספס” זה היה באמת במעט מאוד מהמקרים, לא בסיטואציות של כסת”ח אלא יותר “שמע, זה היה טריוויאלי, היית אמור לגלות”, אבל זו לא הנקודה.
  • מה שראינו זה שהרבה מאוד מהמקרים היו תחת קטיגוריה של “Edge case” . . . .
    • זאת אומרת שלחשוב לבנות טסט שבודק בדיוק את הקומבינציה של כל המקרים ב-TDD זה לא ריאלי, כי לא עובדים ככה ב-TDD
      • אתה כל פעם מוסיף קצת טסט וקצת קוד
  • וראינו שבסוף יש לנו כל כך הרבה משתמשים במערכת שמגיעים למצבים שונים - כי המערכת היא מאוד עשירה ביכולות שלה, ומה שאפשר לעשות איתה . . . .
    • ולכל לקוח יש את החוקים והדברים ה-Local-יים - ובסוף, הקומבינציה של מה שהוא עושה היא Edge-case
  • אז אמרנו “אוקיי - איך אפשר להתמודד עם Edge Case-ים?” צריך לנסות לקחת את מה שקורה ב-Production וממש להריץ אותו על מה שקורה לנו . . . .
(רן) זאת אומרת - להקליט . . . . להקליט, ולהריץ בחושך . . .
(אורי) כשאתה לא יכול לעשות . . . נכון? אתה Mission-Critical . . . . אנחנו ב-Outbrain, יכולים לקחת חלק מתנועת ה-Production, להריץ אותה מול גרסא חדשה, לראות שהכל בסדר - ולא יקרה כלום אם נגלה את הבאג בזה. אבל פה, הבריטי לא יגיע לפאב . . .
  • (איתן) בדיוק, זה מה שהתחלתי להגיד . . .
(רן) אז אתה אומר שחלק מתנועת ה-Production אפשר להסיט, אבל חלק מתנועת הרכבות אי אפשר להסיט . . . .
  • (איתן) אז אתה גם, בעצם ב-Canary Deployment, כשאתה מתחיל להכווין חלק או אחוז מה-Traffic שלך ואז לנטר בעיות ולזהות את זה לפני ולעשות Rollback ולהחזיר - זה הסטנדרט, יחסית, שעושים היום בתעשייה.
    • אבל כמו שאמרתי - אצלנו (א) אין מספיק משתמשים לזה, כי אם אני אפנה User אחד או שניים, זה לא יגיע לך ל-Edge cases
    • ואני Mission Critical, שזה בכלל מקשה עלי לעשות את זה.
    • והשילוב של שני הדברים האלה . . .
  • (רן) וגם אם תיהיה לו בעיה - אז אתה בבעיה . . .
  • (איתן) . . . . כן, אחד הדברים שעשינו בתחקור היה להגיד “בואו נגיד שהיה לנו Canary Deployment - איזה מה מה - On-call-ים האלה זה היה פותר?”
    • וראינו ש-5% בערך מה-On-call-ים זה היה פותר . . . אז אמרנו “אוקיי, זה לא הפתרון”.
    • אנחנו צריכים ממש לקחת את מה שקורה ב-Production ולהריץ את זה לפני שזה מגיע ל-Production
    • הנקודה היא שאתה לא רק בודק - לבדוק האם עשית רגרסיה, בדר”כ בשיטות כאלה אתה מסתכל על Error Codes ומנטר משהו מלמעלה, יש “יותר 502 Errors נזרקים” או ש”ה-Performance ניהיה איטי”
  • אצלנו, לפעמים ברגרסיה הפעולה מצליחה - היא פשוט מחזירה תוצאה שהיא קצת שונה . . . .
(אורי) זה אותו הדבר, במקרים כאלה אתה פשוט מסתכל על מטריקות Business-יות כדי לראות . . .
  • (איתן) אבל פה אין מטריקה . . . התוצאה היא למשל, סתם דוגמא בסיסית: יש לנו Manual edit, וה-User מזיז משהו מפה לפה במערכת.
    • התוצאה של איך שה-Manual Edit נראה היא JSON- של ממש דאטה של לפני ואחרי
    • אם שיניתי משהו בקוד בטעות ופתאום המ-Manual edit נראה אחרת והוא פתאום עשה Outcome אחר ויצר תוצאה אחרת, אז זה ממש להשוות את התוכן של ה-JSON ולעשות ממש השוואה ברמת הדאטה
    • זה כבר משהו שהוא לא מטריקות כל כך שאתה יכול לנטר - וזה הרבה מהבעיות שהיו לנו.
      • שמישהו הכניס איזשהו שינוי בקוד והתוצאה הייתה שה-APIs התנהגו שונה . . . .
      • אז אני ממש רוצה לבדוק את את ה-APIs
    • כך שהבדיקה היא לא Bit-wise או Stream-wise, כי יש לנו Unique IDs שנוצרים אז מן הסתם אלו דברים שונים, והשוואה היא בעצמה פונקציה שצריך ממש לכתוב אותה כדי להתאים אותה לסוג האופרציה שאתה רוצה להשוות.
  • (אורי) השוואה של התוצאות . . .
    • (איתן) כן
(רן) זה קצת מזכיר את הנושא של בדיקות של UI - אתה רוצה לעדכן איזשהו מסך ב-Web או מסך באפליקציה ועכשיו אתה רוצה לבדוק: יכול להיות שהגרסא החדשה היא שונה במשהו מהגרסא הקודמת . . . . זה לא אומר שזה באג: שינית גוון או ששינית קצת את המיקום של הכפתור, אבל הכל בסדר. אבל אם באמת תשווה את זה Pixel-by-Pixel אז כמובן שתגלה “שגיאה”, וזה יכול לייצר הרבה מאוד רעש.
  • (איתן) נכון, אני חושב שכאן זה באמת דומה יותר לבדיקות של APIs - אתה רוצה להשוות API, אבל כן מותר לך לשנות, ה-API לא מחזיר בדיוק את אותו ה-JSON, יש אלמנטים שהם שונים כי הם Generated כחלק מה . . .
(אורי) ברמת השדות שחוזרים?
  • (איתן) למשל, או שאם הוספתי מטריקה או סטטיסטיקה חדשה, שלא הייתה קיימת, וכחלק מהפעולה גם חוזרות סטטיסטיקות.
    • אז במה שהוקלט ב-Production אין את הסטטיסטיקה החדשה הזו שעכשיו הוספתי, ועכשיו הוספתי חדשה - אני צריך לדעת להשוות ולהבין שיש דברים שהם New וזה בסדר, לעומת רגרסיה.
    • בסוף, חשוב לזהות פה את הרגרסיות.
  • אז המוטיבציה הייתה שאנחנו בעצם מקליטים את מה שקורה ב-Production - אני עוד מעט אסביר איך - ואז אנחנו יכולים “לנגן” את הכל על הקוד, לוקאלית אצל מפתח על המחשב, לנגן את זה ב-Jenkins כחלק מה-CI, ולקבל ממש טבלת Regression שהוא נותן לכל הקלטה, עם Diff כזה של “הכל בסדר” או אם יש רגרסיה או Exception או Whatever שהשתנה.
(אורי) ועל זה צריך לעבור בנאדם? או שהוא אומר לך בסוף תוצאה?
  • (איתן) בסוף הוא אומר לך, מן הסתם, “טוב” או “לא טוב”, כלומר Equal או Different . . . .
    • אם זה Equal אז הכל טוב, אם זה Different אז בנאדם צריך להסתכל על ההבדלים ולהגיד “זה בסדר, כי זה בדיוק מה שעכשיו הכנסתי, זה ה-Difference שאני מצפה לראות”.
    • כי בסוף אנחנו מכניסים שינויים אז יהיו לנו שוני לעומת מה שהוקלט ב-Production.
    • אבל אם הוא לא עשה שינוי ופתאום הוא רואה שההקלטות משתנות לו במקום אחר אז הוא . . . מן הסתם הוא יבין שזה לא בסדר.

(אורי) אז להבדיל מ-TDD, שבו אנחנו כותבים את התוצאה המצופה בטסט שלנו עוד לפני שאנחנו לפעמים בכלל כותבים את הקוד, אנחנו קודם כותבים התוצאה המצופה . . . .
  • (איתן) אני אחד מהצדיקים, כן . . . .
(אורי) . . . אבל פה, אין לך את היכולת ממש להגיד מה הולכת להיות התוצאה המצופה - אתה תמיד תצטרך להסתכל על התוצאות וואז להגיד “אוקיי, זה בסדר וזה בסדר . . . . זה מה שציפיתי” . . . .
  • (איתן) לא בדיוק - מבחינתי, הנחת היסוד פה היא ש-Production הוא בסדר, ולכן התוצאה שהוקלטה ב-Production זה מה שאני מצפה שיקרה . . . .
(אורי) אבל עכשיו אתה מכניס גרסא חדשה . . .
  • (איתן) אז כן - אם עשיתי שינוי והוא לא כזה “Behind the scenes” ולא באמת אמור לשנות את ה-API עצמו
    • ברוב השינויים שאנחנו עושים אנחנו לא משנים את ה-API אלא אני מוסיף יכולת חדשה, וכתוצאה מזה נוגע קצת בקוד פה, עושה קצת Refactor פה, דברים כאלה . . .
(אורי) אבל עכשיו, כשתצא מה-Replay - יהיה Diff?
  • (איתן) רק אם תכננתי שיהיה Diff . . .
(אורי) אבל אם תכננת את זה, המערכת טסטים לא יודעת שתיכננת את זה . . . . להבדיל מ-TDD, שבו אתה משנה את מערכת הטסט עוד לפני.
  • (איתן) נכון, אז פה אתה תראה את ה-Diff הזה, המערכת תודיע לך שיש Diff-ים, ממש תראה לך איפה יש הבדלים
  • ואז אתה צריך להסתכל על זה ולראות האם זה Diff שהתכוונת אליו או לא התכוונת אליו.
(אורי) וכמה פעמים יש באג - זאת אומרת, טעות אנוש - מישהו אומר “כן, זה מה שהיה צריך להיות” ודה-פקטו זה לא היה צריך להיות? כי זו טעות-אנוש . . . .
  • (איתן) אתה מתכוון שהוא ראה את ההבדל ו . . . .
(אורי) הוא ראה את ההבדל, המערכת הציפה את ההבדל - ובנאדם, בעין שלו, הסתכל על זה, ראה שיש 15 הבדלים ואולי לא מתעמק בכל אחד, ובשביעי הוא אמר שככה זה צריך להיות . . . .
(רן) בסדר, כל עוד אתה שם לו את זה מול העיניים . . .
  • (איתן) אין לי סטטיסטיקה לזה.
  • אני יכול להגיד הפוך - אני יכול להגיד ולראות בכמה הורדנו את הרגרסיות כתוצאה מהדברים האלה.
    • כמה פעמים אנשים באו אלי, אחרי ששחררנו את זה, ואמרו “וואו, איך זה שינה לי את העולם, זה פשוט גילה לי את הבעיות שברור שהן היו הופכות להיות On-call”
    • כי הכל עובר עם הטסטים וזה טוב ויפה - אבל הנה, יצרתי פה רגרסיה שבכלל לא . . .
(רן) במידה מסויימת, כשיש פחות False-Positive אז אתה פחות תקבל את הדברים האלה . . . אם על כל דבר המערכת מתריעה, אז בסופו של דבר אנשים כבר, אתה יודע, “זאב-זאב” . . . הם כבר לא ישימו לב לזה. אם במערכת, רמת הרגישות שלה היא נמוכה יותר, ובאמת מתריעה בדר”כ על דברים שהם נכונים, מן הסתם תקבל פחות . . .
  • (איתן) אנחנו מתייחסים לזה היום . . . אם יש התרעה אז אין כזה דבר להכניס בלי להסביר למה זה, למה אתה מכניס.
  • אתה חייב לעבור על זה, וכמעט תמיד זה מגלה באמת בעיה.

(רן) אני חושב על בעיות דומות בעולם של Data - כשאתה רוצה, למשל, לשנות משהו בסכמה של Database או באיזשהו Pipeline או איזשהו Processing של Data - הרבה פעמים לבעיות האלה, מאוד קשה לעשות להן Revert, אם יש לך באג, מאוד קשה לעשות Revert לסיפור הזה . . . אתה יודע, זה לא כמו קוד שאתה פורש ואז גילית באג אז אתה עושה Roll-back או Roll-forward אבל זה מהר מסתדר - לא, פתאום גילית שכבר יומיים יש לך Data לא נכון . . . .מה תעשה? עכשיו אתה צריך לתקן את ה-Data.
אז באגים ב-Data זה הרבה פעמים באגים שהם מאוד קשים להתמודדות - וגישה כזאת, אני גם ראיתי אותה קוראת שם, של לבוא ולעשות איזשהו מנגנון של “הקלטה והשמעה מחדש”. אבל שם יש בעיה של, זאת אומרת, שה-Scale הוא לא טריוויאלי . . . יש בדר”כ עלויות מאוד גבוהות, להקים Infrastructure, להקים Cluster נוסף של Spark של אלף או אלפיים Node-ים זה יקר . . . . אם אתה עושה את זה רק לצורך הטסטים אז זה לא כל כך פרקטי.
אז שם, תיאורטית, למרות שזה נשמע לכאורה מאוד פשוט - פרקטית, הגישה הזאת מאוד מאוד יקרה.
  • (איתן) עכשיו, מה שבכל זאת ייחודי באיך שבנינו את זה זה שיש הרבה יכולות להקליט דברים, אבל יש פחות יכולות “לנגן” דברים
  • כי בסוף, כשאתה מנגן משהו אז אתה תלוי ב-State קיצוני של מה שקורה - ה-End-point הזה יכול לקרוא ל-End-point אחרים ויכול לקרוא ל-Database ויכול לקרוא בכלל ל-URL-ים באינטרנט . . .
  • וכשאתה מנגן את זה לוקאלית, אתה רוצה לוודא שאתה חי באותם “תנאי מגרש” . . . . אין לי את ה-Database באותו State וכל הדברים האלה.
  • אז קצת חיפשתי באינטרנט, ולא מצאתי פתרונות קיימים - רוב הפתרונות זה ”בוא נקליט את ה-Traffic ונדע לשלוח לך את זה לסביבה אחרת”
    • אבל, ברגע שזה ככה, ה- State הולך לאיבוד, של מה שקורה מסביבך.
(אורי) בעניין הזה, רציתי לשאול - כל כמה זמן אתם מקליטים?
  • (איתן) אנחנו מקליטים כל פעולה . . .
  • יש פעולות שעכשיו הן Sampling, כי נגיד שזה קורה בתדירות מאוד גבוהה, אבל אם הן זרקו שגיאה אז אנחנו אוטומטית מדליקים אחד והופכים אותו להיות חלק מה-Sample.
  • מה שאנחנו עושים בהקלטה - בעצם בנינו Open Source Framework ב-Python, אנחנו עכשיו בדיוק ב-TS,JS port שלו, שעושים סוג של אינסטרומנטציה,
    • ממש צריך לסמן בקוד, באמצעות Decorator-ים ב-Python, מה מבחינתך זה Input-ים ומה זה Output-ים של הפעולה.
    • ומה שקורה זה שכשאנחנו ב-Production, אנחנו עושים Intercept ל-Input-ים ומקליטים אותם - זאת אומרת, נניח שיש לי קריאה ל-Database . . . .
(רן) רגע - מה זאת אומרת “מה זה Input-ים”? ה-Input זה הפרמטר לפונקציה וה-Output זה מה שהיא מחזירה . . .
  • (איתן) כן, אבל אם האופרציה עצמה קוראת לדברים באמצע?
    • כמו שאמרתי - אם היא פונה ל-Database, אם היא פונה לדברים חיצוניים, אז עכשיו תקבל Input-ים שאם תנגן את הקוד מחדש, תראה שמישהו מנסה לפנות ל-Database - ואין לך את ה-Database הזה, אז אתה צריך . . .
(רן) אתה מנסה למדל גם את ה-Side effects וגם את התלויות ה-Implicit . . . .
  • (איתן) נכון, בסוף זה Sandbox . . . אתה מריץ את ההקלטה, וזה רץ על המחשב שלי, לוקאלית, ולא תלוי בשום גורם חיצוני, וזה משחזר בדיוק את מה שקרה ב-Production.
(אורי) אבל אתה תריץ את מה שרץ לפני חמש דקות - או משהו שהוקלט לפני יומיים?
  • (איתן) אז בדר”כ אנחנו מריצים Random-ית מהשבועיים האחרונים, אז אתה יכול איך שאתה רוצה.
  • למשל, אחד השימושים הנוספים זה שבכל פעם שעף לנו Error ב-Production, וזה מגיע ל-SENTRY, אנחנו מוסיפים ל-SENTRY את ה-Recording ID.
    • זה היה Side-effect שלא תכננו אותו בכלל, אבל עכשיו כשיש שגיאה אז זה לא “לך תביא לי שחזור”, “לך תעשה לי . .” - זה Copy-Paste של ה-ID הזה וזה מריץ את זה לוקאלית.
    • זה אחד הדברים ששיפרו את הפרודוקטיביות של המפתחים בטירוף
    • וזה עדיין - כל כמה ימים מישהו בא אלי ואומר “פעם הייתי צריך לבקש שחזור ולחפש - עכשיו אני עושה Play Recording וזהו”, פותר שלושה באגים ביום במקום אחד בחמישה ימים עד שאני מצליח לשחזר אותו.
(אורי) מתי יש לו זמן לכתוב באגים? . . . .
  • (איתן) זה תמיד יש . . . אתה מפנה לו זמן לכתוב באגים.
  • אבל כשאנחנו עושים Interception, אנחנו ממש מסמנים על הפונקציה - יש לי פונקציה שניגשת ל-Database, אז אני אסמן עליה שהיא Input
    • ומה שקורה זה שאנחנו נקליט את הפרמטרים שפנו, בתור Query - זה ה-Key.
    • וה-Result זה ה-Value.
  • ואז בתוך ההקלטה, זה ממש מכיל Dictionary של Keys כאלה, של פניות לכל מיני Input-ים ואת ה-Values שחזרו.
    • ואז כשאתה מריץ את זה לוקאלית, אז הקוד שלך אמור לייצר את אותו ה-Query ל-Database, ולכן להחזיר את אותו הדבר.
    • ואם הוא לא - אז פתאום יעוף Exception ב-Recording . . . אם שינית משהו, למשל, ולא התווכנת, אז פתאום ב-Recording לא יהיה איך לשלוף את ה-Data שהיה ב-Production ותקבל No such Key Error, או Whatever.
  • החסרון הוא שאם באמת שינית בכוונה ואתה באמת רוצה לעשות Query חדש, אז ההקלטה כבר לא כל כך רלוונטית, כשתעשה מניפולציה בזמן ההקלטה.

(רן) אז באמת רציתי לשאול על המודולריות של מערכת כזאת, כי זה נשמע כאילו יש לך איזושהי קופסא שחורה ואתה מקליט את כולה - אם כשמשתנה רכיב אחד קטן בתוך הקופסא הזאת, האם זה עושה מיד invalidation לכל מה שהקלטת? . . .
  • (איתן) תראה, Input-ים זו פנייה לעולם החיצון, הפניות שלך לעולם החיצון שמחוץ ל-Service . . .
  • כשאתה עושה שינוי, אתה לא נוטה לשנות את העולם החיצון, כי בעולם החיצון . . . אתה לא נגעת בו עכשיו, בחלק מהדברים האלה.
  • אז רוב הדברים האלה הם בסוף לוקאליים ל-Service, והם גם לא צריכים עכשיו סביבה שלמה של כל ה-Service-ים כדי לנגן את ההקלטה
    • כל Service אוטונומית נבדק . . . .
(רן) הבנתי - זאת אומרת שלכל Service יש הקלטות משלו?
  • (איתן) נכון, ממש כל End-point מוקלט והוא Encapsulated, ועכשיו אני יכול להריץ אותו
    • אני מריץ 500 הקלטות של ה-End-point הזה, ולא צריך שום Data חיצוני ושם דבר.
  • כמובן שאני צריך לשים את ה-Interceptor-ים במקום הנכון ולא לפספס דברים.
    • למשל - יש לנו התנהגות שתלויה ב-Environment variables ושכחנו לעשות Interception לזה והרצתי לוקאלית, וה-Enviroment שלי על המחשב לא כמו ב-Production, אז הקוד שם של ה-If . . . .
    • לא הבנתי למה אצלי זה מתנהג כמו X ו-Y ו . . .
(רן) רגע, יש יותר כייפי - תלוי בכמה מקום יש על הדיסק, תלוי באילו עוד תהליכים יש, יש כל מיני דברים כאלה . . .
  • (איתן) נכון, לכן אתה מגדיר את ה-Environment variable גם כ- Input שאתה צריך לעשות לו Interception, למשל בדוגמא הזאת.

(רן) יש לזה עלות משמעותית? להקלטות, לעלות בזמן פיתוח, לכל מיני עלויות נוספות שאולי לא לקחנו אותן בחשבון? או שאולי . . .
  • (איתן) עלות הפיתוח זו בניית התשתית - זו עלות . . .
(רן) כן, זו עלות הפיתוח - האנוטציות (Annotations), אולי יש באג, צריך לחשוב ולתקן . . . .
  • (איתן) בהתחלה היה יותר . . . . בחודשיים הראשונים, הזמן שאתה צריך לעשות את האינטרציה.
    • נגיד, אחרי שבנינו את ה-Framework עצמו - להתחיל לעשות לו אינטרציה
  • אז בהתחלה יש הרבה נפילות False כאלה, שהוא לא מצליח לשחזר בדיוק את ההרצה ויש כל מיני דברים עד שאתה מזהה בדיוק את כל המקומות שפספסת ב-Interception.
  • אבל ב-Day-to-day אנחנו לא . . .אתה לא מוסיף יותר מדי Inputs חדשים, זה קורה אחת-לחודש, שפתאום מישהו שאל שאלה . . . .
    • אז בהקשר הזה - לא.
  • העלויות הן יחסית זניחות, אנחנו שומרים את הכל ב-S3 עם Life cycle של שלושה חודשים . . .
    • וזה שטויות, זה זניח
  • גם התשתית בעצם שומרת את זה ל-S3 באופן א-סינכרוני, כדי שזה לא יפגע ה-Latency של הפעולה, אז זה מקליט וברקע זה ב-Thread-ים, שולח את זה ל-S3.
    • ואתה יודע - S3 זה לא באמת עולה הרבה
    • כמובן שזה לא מתאים ל-Scale - להקליט כל דבר ב-Scale של מיליון פעולות בשנייה - שם צריך להגדיר Sampling, אז אתה תומך ב-Sampling.
  • יש לזה הרבה דברים מובנים כדי לתמוך בכל מני סוגים שונים של Interception-ים של Input-ים שונים.
  • ובסוף זה הכל Open source ב-Python . . . .

(רן) אני גם יכול לראות איך זה, מעבר ללמצוא רגרסיות ומעבר ללמצוא באגים - איך זה יכול לעזור לך לשפר את הקוד, במובן הזה שאתה עולה ככה על Smell-ים, אתה עולה ככה על פונקציה שיש לה הרבה מאוד תלויות ואתה מבין שיש פה איזושהי בעיתיות, יש פה איזושהי פונקציה שעושה יותר מדי דברים, ואולי נכון יותר לפרק את זה ולעשות איזושהי מודולורזציה. אם אתה רואה שיש הרבה פונקציות שתלויות באותו הדבר, אז יכול להיות שיש פה מקום לייצר איזשהו Service . . . . זה מציף הרבה דברים שאולי קודם הם היו Implicit ומי שמכיר ממש טוב את הקוד יודע אתה זה, אבל בנאדם חדש שנכנס פנימה, עם עיניים חדשות שנכנסות פנימה, הוא לא היה מכיר את זה - אבל עכשיו, כשאתה רק מסתכל על האנוטציות אז אתה יכול מיד לראות את זה.
  • (איתן) כן, זו נקודה מעניינת
  • אחד הדברים, עוד Side-effect שראינו, הוא שבעצם נקטנו בגישה פרו-אקטיבית של תיקון בעיות -
    • להסתכל על SENTRY בלי שפותחים לנו Support cases, ולהתחיל לזהות את ה-Issue-יים ה-Repetitive-יים ולהתחיל לפתור אותם.
    • אז עכשיו יש לנו Recording ID ואני יכול להריץ את זה - אני רואה “הנה הבעיה!” ואני מתקן
      • אבל אז אני אומר “רגע - בעצם, אולי יש לי עוד דוגמאות של הבעיה הזאת, בואו נבדוק שתיקנתי את כולן”.
    • אז מה שאנחנו עושים זה שאנחנו מוסיפים להקלטה גם מטה-דאטה, שמאפשר לבקש “תביא לי את כל ההקלטות שיש להן את הפילטר המסויים על המטה-דאטה”
      • אז למשל זרקנו איזושהי שגיאה, אנחנו שמים את ה-Description של השגיאה כחלק מהמטה-דאטה - ואז זה ממש מסווג את זה
      • “תביא לי את כל ההקלטות שבהן עפה השגיאה הזאת, תריץ לי אותן עכשיו, אחרי שתיקנתי” - ופתאום אתה רואה שהופ! יש פה עוד 50% מה-Case-ים שלא גיליתי בתיקון הזה, ספציפית . . .
      • (אורי) זה לא תפס בתיקון . . . . בעצם לא תיקנתי.
      • (איתן) נכון - ואז אתה יכול לתקן אותם
    • ואתה יכול להוציא מטריקות, לראות כמה כשלונות יש יש לי בכל End-point, וכל מיני מידעים לפי איזה סוג וכל מיני דברים.
  • אבל מטה-דאטה משמש לא רק כדי לפלטר שגיאות - לפעמים אני אומר אוקיי, אני עכשיו יודע שאתה יכול לפלטר על לקוח מסויים, אתה יכול לפלטר על ממש Properties שהועברו ל-End-point הזה
    • אז אתה אומר, נגיד, שאסטרטגיה מסויימת שהופעלה ב-End-point הזה - אז אני שומר במטה-דאטה איזו אסטרטגיה הופעלה
    • ואז אני יכול להגיד “תביא לי את כל ההקלטות של של האסטרטגיה הזאת” - כי עכשיו נגעתי בקוד של האסטרטגיה הזאת.
    • אז זה לא רק ברמת ה-End-points אלא גם ברמת ה-Properties של הפעולה.
  • כמובן שהכל צריך להיות Light-weight, כי זה לא כל ה-Payload של הפעולה - זה צריך להיות שדות Natives כאלה, שפשוטים לפילטור.

(רן) Tracing אתם עושים גם? [להרחבה - 433 Breaking Down Observability with Nitay Milner]
  • (איתן) כן, אנחנו עושים Tracing . . . .
(רן) זה מתחבר איכשהו, שתי המערכות האלה? . . . .
  • (איתן) לא ממש . . . כלומר, הנקודה היחידה היא באמת ה-Recording ID הזה, שמופיע לנו ב-SENTRY וכו’.
    • זה השימוש המרכזי, הייתי אומר.
(רן) כי אני מניח . . . אני מנחש שלפעמים יש באגים של תזמון. זאת אומרת, כשהכל מהר ואין עומס אז זה עובד טוב, אבל כשיש עומס על איזשהו Service ופתאום זמן התגובה שלו יותר איטי, אז פתאום אתה רואה את הבאג - ולצורך זה Tracing יכול לעזור.
  • (איתן) כן, אצלנו זה פחות ה-Use case. אני יכול להבין למה במערכות אחרות . . .
  • אבל אין ספק שאפשר יהיה להוסיף ל-Tracing - להביא את כל ה-Recording IDs של כל ה-Service-ים לאורך השרשרת, שכרגע קרו
    • ואז להתחיל לנגן נקודה-נקודה
  • עכשיו, במערכת החדשה שאנחנו משחררים, שהיא כולה Serverless-ית, אז היא גם כתובה ב-TypeScript, אז אנחנו עושים Port במערכת הזאת ל-TypeScript
    • כי ראינו כמה זה אפקטיבי, באמת - המערכת היא עוד יותר Mission-Critical, אז אנחנו עוד יותר From Day 1 רוצים לצאת מוכנים עם הכלים
    • ושם באמת יש הרבה Lambda-ות שמפעילות Lambda-ות שמפעילות Lambda-ות . . . . ועוברות דרך SQS וכו’
    • אז שם זה באמת . . . .

(אורי) והרבה פעמים, בגלל שזה SQS, אז דברים יהיו א-סינכרוניים, מן הסתם?
  • (איתן) כן
(אורי) וזה מקשה על Tracing . . .
  • (איתן) נכון, אבל בסופו של דבר אותנו מעניין ממש הכניסה הסינכרונית לפונקציה והיציאה ממנה
    • אם היא קראה לדברים א-סינכרוניים ובסוף חזרה מהם עם איזשהו Input, אז זה יהיה חלק מה-Interception של אותו הדבר, אז . . . .
(רן) אבל אם אתה מקליט רק ברמה . . . נחזור לרגע כמה דקות קודם - אם אתה מקליט ברמה של Service, אז בעצם אתה מפסיד את האינטגרציה . . . זאת אומרת, בדר”כ דברים מעניינים או שגיאות מעניינות מתרחשות כש-Service אחד קורא ל-Service אחר, והוא קורא ל-Service שלישי וכו’.
אז את זה אתה לא מפסיד?
  • (איתן) הרבה פעמים, הבעיה היא בסוף ב-Service השלישי, והוא זה שזורק לי Exception ל-SENTRY שמשהו קרה לא בסדר
    • ולא כל כך מעניין אותי איך הגענו לשם - מעניין אותי מה שבור בקוד הזה.
  • אז נכון - זה לא מרים סביבה מלאה ואז מנגן, כי אז אתה נכנס עוד פעם לאותה הבעיה של איך אתה משחזר את כל הדאטה ומריץ על 10,000 דגימות שונות Random-יות . . . .
(רן) אבל תראה, Scenario שהייתי רואה לא מעט זה שאותו Service שלישי - ה-Maintainer שלו שינה משהו ב-API, ומבחינתו הכל בסדר. הוא עשה והריץ וראה שיש Diff ואמר “אוקיי, זה בדיוק מה שהתכוונתי”. מחר בבוקר, כשמישהו אחר גם ישתמש ב-API שלו ואולי לא מודע לשינוי הזה - לפעמים זה שינוי בסכמה, לפעמים זה שינוי סמנטי שאתה לא יכול לתפוס - פתאום דברים נשברים.
  • (איתן) נכון, זה לא מיועד לזה.
    • זה מיועד לרמת ה-Service שלך, לבדוק שאתה לא יצרת Regression.
    • אז מי שהריץ את ההקלטות והחליט “לא, זה בסדר השינויים האלה” - אז היה צריך לעשות את זה בידיעה.
  • זה לא מבטל את הצורך לעשות ממש טסטים בסביבה שלמה, אבל מאוד מאוד קשה לעשות בכזה Scale וכזו כמות . . .
    • כשאתה מדבר על סביבה אחרת ויש לך הרבה - נגיד Database חיצוני ו-State שאתה תלוי בו - אני בכלל לא חושב שזה אפשרי לעשות את זה ממש טוב.
    • לקחת, נגיד, 10,000 דגימות של לקוחות שונים מפוזרים Random-ית על המרחב ולהריץ את זה איכשהו בסביבה צדדית שהיא . . . כשה-Database כלל לא שומר על התמונה . . .

(רן) אז אני שומע שאתם עכשיו עובדים על קוד פתוח של אותו רכיב . . . .
(רן) חוץ מכם יש עוד משתמשים?
(אורי) איך הוא נקרא?
(רן) Equalizer זה מעניין . . . מה עושה Equalizer? יש סראונד? . . .
  • (איתן) אז בעצם, כשאתה מנגן מחדש, אתה צריך, כדי לבצע את ההשואות, צריך איזשהו Plug-in שאומר איך אני משווה דברים.
  • אז ה-Equalizer אחראי על איזה שלושה-ארבעה Plug-ins שאתה צריך לממש כדי לבצע את הניגון ולבצע את ההשוואה.
(רן) . . . על מנת לעשות את התמרות הפורייה הנדרשות כדי להוריד את הטונים . . .
  • (איתן) נכון
(רן) מעניין . . .
  • (איתן) כן . . . אז בסוף, בשונה מהרבה גישות היום שהן מאוד דומות - שלא מתערבים לך בקוד, אני עושה הכל מבחוץ ואתה רק עושה פה איזה Import - פה זה לא המצב.
    • המצב פה הוא שאתה צריך לשים Decorator-ים במקומות הנכונים
    • ואתה צריך לכתוב Plug-In אם ההשוואה היא לא סופר-טריוויאלית - אז ה-Plug-In-ים שלך יכולים להיות יותר ויותר מורכבים.
    • יש לזה ידע אינטימי . . . מי שכותב את זה - צריך שיהיה לו ידע אינטימי עם ה-Service
    • והרבה פעמים, ה-Service-ם - יש להם כזה Base-class שאתה משתף . . . יש לך איזושהי תבנית חוזרת בהרבה מאוד מה-End-Points שלך.
  • אז אצלנו, נגיד - בסוף יש לנו שני סוגי End-Point - או שזה celery-based או שזה HTTP-Based - והיה מאוד קל לעשות את ה-Interception בצורה שהוא . . . .
(רן) אבל זה לא Black-box, זאת אומרת . . . זה לא Black-box, אתה כן צריך להכיר את ה-Server-ים שלך; מצד שני - זה לא Unit Test - זה לא בודק פונקציות יחידות, זה בודק איזושהי יחידה - קראת לזה “Service”, למרות שאתה תכל’ס יכול גם לבדוק יותר מ-Service אחד, נכון?
  • (איתן) אתה יכול בסוף להחליט לשים Decorator של איפה מתחילה אופרציה בכל מקום בקוד
  • אפשר להגיד שקריאה אחת . . . תיאורטית אתה יכול לעשות את זה ברמת הפונקציה, אבל זו לא המטרה . . .
  • המטרה היא לנגן משהו שהוא יותר גדול.

(רן) טוב, מעניין . . . . שיהי לכם בהצלחה עם הפונקציות Lambda בכל הסיפור הזה, כי שם זה נשמע לי יותר מורכב . . . לבדוק פונקציה לכשלעצמה זה יחסית קל, אבל ברגע שיש לך כמה מאות שעובדות אחת עם השנייה דרך SQS-ים ודברים א-סינכרוניים, זה ניהיה כבר הרבה יותר מורכב. אני מניח ששם זה כבר לא יהיה רק על פונקציה בודדת?
  • (איתן) לא, התשתית הזאת כן תיהיה ברמת הפונקציה הבודדת - יהיו . . .
  • כמובן, יש לנו את הדרכים להרים סביבה שלמה ולהזרים אליה Traffic וכו’ - אבל תמיד ה-Coverage של ה-Edge cases יהיה הרבה יותר קטן בסיפור הזה.
    • ושם גם יש את הטריק של Lambda-ות - מכיוון שאנחנו לא רוצים להתערב עם ה-Latency של הפעולה, ו-Lambda מתחילה ומתה, ואני בסוף צריך לאסוף את כל הדברים בדרך - אז יש פה טריקים של איך אתה בכל זאת שולח את ההקלטה.
    • יש עבודה שצריך במימושים של ה-Abstract Classes האלה, כדי להתאים אותם לסביבה של Lambda-ות, לעומת Flask, לעומת celery, וכו’.
  • יש לנו גם קצת Contributors מבחוץ, ואנחנו מאוד נשמח שאנשים יתרמו וישתמשו בזה ויפיקו את הערך . . . אנחנו באמת מפיקים מזה ערך.

(רן) אני חושב שהאתגרים קיימים בעולם ה-Tracing - אם תסתכל על Design של Jaeger או של של מערכות A-sync אחרות, אתה תראה שהן באו לפתור אתגרים מאוד דומים, של איך לשלוח נגיד, את ה-Trace לפני שה-Service מסיים את החיים שלו, ויש לזה כל מיני סוגים של פתרונות, בין אם זה לשלוח מקומית דרך UDP ואחר כך לאסוף את זה, או כל מיני פתרונות מסוגים אחרים.
(אורי) אני יודע שב-Outbrain עשו Cross-Service Tracing וכו’ . . . הדבר שדומה אולי, קצת, ל-Lambda-ות זה שעשינו את זה גם על עבודות א-סינכרוניות, על קריאות א-סינכרוניות בין ה-Service-ים.
(רן) אתה מוסיף איזושהי Envelope ל-Message, כדי לדעת מה ה-Trace ID.
  • (איתן) אנחנו משתמשים ב-New Relic וכל מיני . . . Lumigo ודברים כאלה
  • אבל בסוף זה בא להראות לך דברים - זה לא נותן לך את היכולת הזאת, של להריץ מחדש, לקבל שחזורים - שזה ה-Added-value פה, זה מה שהתשתית הזו בעצם מיועדת עבורו.
(רן) עכשיו כשאתה אומר, זה נשמע כאילו הגיוני שהם גם יעשו את זה, אבל בסדר . . .
  • (איתן) היו כבר כמה פניות, בעקבות . . . ששמעו אותי מדבר על זה, אז יזמים שרוצים לבנות ממש חברה סביב הנושא
    • אני חושב שאפשר ממש לבנות חברה סביב הסיפור הזה, בסוף אבל צריך . . .
    • אני חושב שזה לא יעבוד בלי הגישה של . . . המפתח צריך לדעת איך להשתמש ב-Framework הזה - ולהשתמש בו, לשים את ה-Interception במקום הנכון.
    • כמובן שאפשר לבוא עם ה-Out-of-the-Box Interception כבר מוכן וכל מיני דברים כאלה, אבל יש דברים אינטימיים שאתה חייב לדעת כדי שזה באמת יצליח לנגן את זה נכון.
(אורי) אם היה לי שקל על כל סטארטאפ שבא ואומר “כן, יש לנו איזשהו פתרון לבעיה בעולם ה-Production” או בעולם כזה או אחר, וכן, בסדר - פתרנו את זה לפני שלוש שנים, או לפני . . . .

(רן) טוב, איתן - אז זה נשמע סופר-מעניין וגם מאתגר. נוסיף את הקישור ל-GitHub, אני מניח, בפודקאסט עצמו [כן]. אני גם מנחש שאתם מחפשים מהנדסים, פה ושם? . . . .
  • (איתן) כן . . . . כמובן, אנחנו צריכים לגייס עוד לפחות איזה 150 איש השנה, שכוללים . . .
(רן) אז ספר קצת על ה-Stack הטכנולוגי - הזכרת ככה קצת, אבל איך בגדול . . . מה עושים בחברה? באילו טכנולוגיות עובדים?
  • אז אנחנו מערכת שכולה Deployed ב-AWS - הכל Cloud-based, אין שום דבר On-Premise.
  • אנחנו באמת עובדים עם מכוון רחב של דברים - מבחינת שפות זה מ-Python ו-TypeScript ו-JavaScript ו-Node.js וכו’.
  • אנחנו עובדים הרבה מאוד עם Lambda-ות וכמובן Kubernetes והכל - זה או Kubernetes או Lambda-ות
  • וכל צוות, או כל מודול - אנחנו עובדים ב-Product teams - יש לו Stack טכנולוגי שרלוונטי אליו
    • יש צוותים שעובדים Pure-Serverless, יש צוותים שעובדים Mix & Match ביניהם, יש צוותים שבעיקר על Kubernetes Pods - הכל תלוי ב- Use case ,כמובן.
  • ובאמת מחפשים אנשים שרוצים מצד אחד לעבוד במשהו שבאמת עושה טוב לעולם - לא כקלישאה אלא באמת לשפר את התחבורה הציבורית והאימפקט של זה, גם על איכות הסביבה, הוא מאוד גדול
    • אני לא זוכר אפילו את המספרים, כמה מאות-מיליונים של Emissions ירדו כתוצאה מהשימוש במערכת שלנו, שמתכננת גם רכבים חשמליים
      • זה אחד האתגרים היום, שאוטובוסים חשמליים הם הרבה יותר קשים לתפעול, וצריך מערכת חכמה לתכנן אותם כדי להיות מסוגל להשתמש בהם בכלל
      • איך אתה טוען אותם, מתי אתה טוען אותם . . . .
    • (רן) בגלל הפסקות הטעינה שנדרשות . . .
      • (איתן) כן - מתי לטעון וכמה Capacity יש לך ואיזה סוג מטען . . . . מלא שאלות שצריך לעשות, שבדיזל אתה פשוט מתדלק ובסוף היום רואה את האוטובוס שוב פעם בתחנת דלק
  • אז יש הרבה אתגרים - גם אלגוריתמיים וגם לבנות מערכת, כמו שאמרנו, Mission-Critical SaaS Platform
  • והאנשים אצלנו עם מוטיבציה גבוהה להפעיל את היכולות שלהם ובאמת לנסות להשפיע על היומיום של כל האנשים ולהעביר אותם לתחבורה ציבורית.
(רן) איפה בישראל?
  • (איתן) אנחנו יושבים ממש במרכז, היום בבניין ToHa, ממש שם בשלום . . . .
  • אני, למשל, מכרתי את האוטו שלי - יש לי אוטובוס מהבית בכפר סבא ממש עד למשרד.
    • מבטיח שלא נגעתי במערכת ודאגתי שזה מה שיקרה אלא גיליתי את זה במקרה . . .
    • אנחנו ממש ב-Hub של תחבורה ציבורית ומעודדים את כולם לבוא עם תחבורה ציבורית ומאוד לא נוטים לבוא במכוניות לעבודה.

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


האזנה נעימה ותודה רבה לעופר פורר על התמלול!
  continue reading

152 פרקים

Artwork
iconשתפו
 
Manage episode 322741079 series 2497397
תוכן מסופק על ידי רברס עם פלטפורמה. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי רברס עם פלטפורמה או שותף פלטפורמת הפודקאסט שלו. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.

היום אנחנו מארחים באולפן בכרכור את איתן ינובסקי בשנית: איתן התארח בפודקאסט ב-2018 (Before Covid), אז דיברנו על כמה אתגרים טכנולוגיים מעניינים שיש בהחברה שלו - Optibus - והיום נדבר על עוד אתגרים.

ולפני שנצלול לאתגרים, איתן - ספר לנו קצת על עצמך ועל Optibus
  • (איתן) אז אני איתן, ה-CTO וה-Co-founder של Optibus; עוד רגע נושק לגיל 40, עבר זמן . . .
  • אנחנו בונים פלטרפורמה לתכנון וניהול של תחבורה ציבורית ושל הסעות המונים, שממש אחראית על תכנון של איך אנחנו הולכים להסיע מיליונים של אנשים ברחבי העולם.
    • היום, בפועל, אנחנו פרושים כבר בלמעלה מ-30 מדינות ומתעסקים בהסעות של 2.5 מיליארד אנשים, ברמה שנתית.
(אורי) פתאום, כשאתה מדבר על זה - כאילו בא לי לשאול אותך על הקורונה, אבל זה נראה לי . . . . היא עשתה לכם משהו בימים האלה, כשהתחבורה הציבורית הפסיקה?
  • (איתן) אז זו באמת שאלה מעניינת - כשהתחילה הקורונה אז כמו לכולם היו לנו קצת חששות, בפרט לגבי תחבורה ציבורית, אבל . . .
(רן) היא לא הפסיקה, רק השתנתה . . . זה באמת אתגר מאוד גדול למי שמתכנן . . . .
  • (איתן) בדיוק, כי במקום להפסיק . . . היו שבועות שזה ממש הפסיק, נגיד בסגר המוחלט בישראל, אבל אז זה הפך לגלים של “עכשיו אנחנו צריכים 50% או 20% או 80%”, ברמה ממש שבועית, וזה משתנה.
    • זה דווקא עשה אפקט הפוך - שפתאום הרגישו את הצורך במערכת כמו שלנו,
      • במקומות שהשינויים הם יחסית איטיים - פעם בחצי שנה או שנה - ועכשיו אני צריך פתאום להגיב לדרישות של שינויים ברמה השבועית . . . .
(רן) ניתן רק בשתי מילים, למי שלא זוכר את תקציר הפרק הקודם - בגדול, במקום לעבוד עם טבלה ונייר שבהם רושמים מי נוהג באיזה אוטובוס ואיזה קו הוא עושה, אז Optibus מתכננת את כל זה, ועוד הרבה יותר, מן הסתם - אבל עושה את זה באופן אוטומטי ויעיל. כך שתכנון לוחות הסעות וכל מה שקשור בזה - אם זה משתנה ברמה יומית אז זה כבר לא פרקטי לעשות בידי אדם, אבל Optibus יודעת לעשות את זה.
  • (איתן) נכון, ומאז גם התרחבנו הרבה יותר במה שאנחנו עושים, מרמת תכנון הרשת ואיך שזה מגיב לביקושים והלוחות זמנים
    • רכבים, נהגים . . . ברמה של תפעול יומיומי ואיך להגיב למה שקורה ביומיום וכו’.
    • דווקא בקורונה פתאום נוצר צורך הרבה יותר גדול במערכת - דווקא הייתה לנו את אחת השנים הטובות, שלאחריה הגיע גם ה-Round C שעשינו.
    • היום אנחנו Post Round C
  • היום אנחנו כבר באיזור ה-330 אנשים - אני חושב שבפעם האחרונה שדיברנו היינו באיזור ה-50-60, אני לא זוכר בדיוק את המספרים
  • ובסופו של דבר, כמו שאמרתי, אנחנו מסיעים מיליונים רבים בעולם - הלקוחות שלנו משתמשים במערכת כדי לתכנן איך להסיע את האנשים הללו בצורה מיטבית.
(רן) אז הלקוחות זה חברות אוטובוסים דוגמת “אגד”, לא יודע אם כלקוח ספציפית שלכם אבל כדוגמתם, בעולם . . .
  • (איתן) נכון, אגד הם לקוח ספציפי שלנו, אפילו אחד הראשונים, אבל כן - חברות כאלו בעולם.
    • בנוסף - לא רק: גם חברות שבעצם . . . למשל בניו-יורק יש חברות שהן חצי-ממשלתיות שאחראיות על התחבורה
    • אבל גם חברות כמו Facebook ו-Apple שהן לקוחות שלנו, ל-Commute של ה-Employees’ Shuttle שלהם
    • זה צי של מאות אוטובוסים שיש להם שם.
  • אז בעצם כל התעסקות במסות גדולות של אנשים, שצריך לתכנן את זה מראש ולא רק להגיב on-the-fly -
    • כי אתה צריך לבנות רשת שתיהיה יעילה, אחרת התפעול יהיה מאוד לא יעיל.
(רן) מבחינת התפעול, לא הביצוע - הנהגים הם לא הנהגים שלכם, האוטובוסים לא שלכם . . . .
  • (איתן) נכון, אנחנו רק SaaS ו-Everything is on the Could - אנחנו לא מספקים שירותים מעבר לזה.

(רן) כשעשינו את ההכנה לפודקאסט, ראינו שאחד האתגרים שצצים זה ש”אוקיי, אז מה קורה אם הוספתי פיצ’ר - תיקנתי באג, אני חושב שתיקנתי באג ואני לא רוצה שאותם 2 מיליארדים שמחר נוסעים בבוקר פתאום ימצאו את עצמם בלי אוטובוס . . . . “.
אז איך עושים QA למערכת שכזו?
  • (איתן) בעצם אנחנו Mission Critical SaaS system, והמשמעות של רגרסיות - ה-Impact של זה בסוף משפיע על התפעול של התחבורה וגם יכול להגיע למצב שאי אפשר להוציא למחרת את התחבורה, או אפילו ב-Day-to-Day . . .
(אורי) עכשיו אתה חייב לתת דוגמא לבאג ומה שקרה . . . .
(רן) “אז כשעברנו מהמערכת המטרית למערכת של המיילים, כל האוטובוסים עצרו שישה מייל לפני התחנה” . . . . [How NASA lost a 327 Million Dollar Mission to Mars]
  • (איתן) השוליים צרים מלהכיל את כל הבאגים שקרו לנו ואת הפאדיחות . . .
  • אבל אתה יודע - יש את הרגעים האלה שמכניסים משהו וזה מקריס את ה-Production פתאום, וככל . . .
    • בהתחלה, נגיד כשזה היה קורה לנו לפני חמש שנים, ה-Usage במערכת לא היה כזה גבוה ולפעמים היה לוקח אפילו 20 דקות עד שמישהו שם לב.
    • עכשיו זה תוך שלוש שניות - ה-Support מתחיל להפציץ אותנו בדברים שלא עובדים, אז אתה מבין את ה-Impact של כל . . .
(אורי) כי מתקשרים אליהם?
  • (איתן) גם יש Monitoring וגם כן - ה-Support שמתקשרים אלינו.
    • בסוף ה-User-ים של המערכת שלהם, זה מה שהם עושים ב-Day-to-Day - נכנסים לעבודה, פותחים Log-in ל-Optibus ומתחילים לעבוד
    • ואם משהו לא עובד אז . . .
(אורי) וזה “הסדרנים”?
  • (איתן) זה מתחיל מאנשים שמתכננים את רשת הקווים, עובד לאנשים שאחראים על שיבוץ תוכנית הרכבים והנהגים ובסוף . . . .
  • הסדרנים זה יותר ה-Day-to-Day - עכשיו אני צריך לתפעל את מה שקורה
  • ויש גם את האפיק של התכנון - מה עושים מחר ובעוד שבוע ובעוד חודש?
    • איך אני מגיב ל-FIFA, למשל - יש אירוע לתכנן . . . .
    • משתמשים בנו כדי לתכנן לקראת אירועי ספורט כמו אליפויות עולם וכו’.
    • אז כן - משתמשים מהסוג הזה.
  • הסדרן - זה כמובן הכי קריטי מבחינתו, כי הוא ממש עכשיו מטפל ברכבים שנמצאים על הכביש וצריך להתמודד עם מה שקורה שם, וכשהולכים שנה אחורה זה ניהיה . . .
(אורי) אז רק כדי שנקבל את הסדר-גדול של מה שקורה כשיש באג משמעותי . . . .
  • (איתן) תחשוב על זה ש-60% מהתחבורה באנגליה מתוכננת באמצעות המערכת שלנו . . . אם הכנסנו משהו שבאמת, לצורך העניין, כל כך משמעותי שהוא באמת Crippling של כל המערכת, אז למחרת - או כרגע, תלוי באיזה רכיב אתה מקלקל במערכת - זה יכול ממש לדפוק את ה-60% . . . לגרום לבעיה בתחבורה, ש-60% מהנסועה . . .
  • (איתן) כן . . . .לא הגענו לסיטואציה כזו אף פעם, בדרך כלל אם אני אתקע אז זה על דברים של עוד כמה ימים, לא ממש ב-Real-time, זה קטסטרופלי.
    • אבל כן - צריך לדאוג שזה לא יקרה, ומן הסתם היו הרבה Crisis-ים ובכל פעם השתפרנו ובנינו דברים ויכולות כדי למנוע ושזה לא יקרה יותר, דברים כאלה.

(רן) אז כמו שאתה אומר, יש פה שילוב של מערכת SaaS, זאת אומרת שזה Software as a Service וזה לא שאתה שולח דיסקים לחברת האוטובוסים - זה הכל נמצא שם בענן ואתה יכול לעדכן את זה בכל דקה, ואני מניח ש-Continuous Deployment זה כבר “חדשות דאשתקד”, מצד אחד. מצד שני, כמו שאמרת זה Mission Critical, וזה אומר שיש אנשים שתלויים באופן קריטי בזה שהמערכת תפעל - ותפעל נכון, לא רק תפעל . . .
  • (איתן) נכון, ועוד דבר שמאפיין זה שאין הרבה משתמשים שונים במערכת
    • זה לא, נגיד, Facebook - כשיש לך עשרות מיליוני משתמשים ואתה יכול, אולי, לעשות נזק לאחוז מסויים.
    • מעבר לזה ש-Facebook הוא לא Mission Critical . . . אולי אפשר להתווכח על זה עם כל מיני אנשים, אבל במציאות . . . .
(רן) תלוי במשטר . . .
  • (איתן) תלוי במשטר . . . יחסית יותר קל להגיד “אוקיי, בואו נפרוש משהו לאחוז אחד מהאוכלוסיה”.
  • אצלנו, בסוף המשתמשים זה לא הנוסעים אלה אנשים האנשים שמתכננים את התחבורה.
    • אז זה מאות משתמשים - גג - בו-זמנית, ואחוז אחד זה כבר לא מספר Significant-י לעשות שום דבר
    • מעבר לזה - אפילו אם תדפוק לאחוז האחד הזה משהו שהוא קריטי, זה עדיין עלול לייצר בעיה במקום כמו אם האחוז הזה עכשיו אחראי על התחבורה בלונדון או משהו כזה, ואז אתה מייצר שם נזק.
(רן) אני חושב, דרך אגב, אם אני לא טועה, ב-Waze הם אמרו שישראל זה כר-הניסוי שלהם . . . . סוג-של, כן - לא נוציא את הדברים מהקשרם [הנה הקשרם - 419 Navigation @Waze], אבל שפיצ’רים חדשים יוצאים קודם כל במדינה מסויימת, שיודעים ששם יש יותר רצון לקבל חדשנות, ורק אחר כך מעבירים את זה לשאר העולם.
זה משהו שאתם עושים גם?
  • (איתן) אז אנחנו במתח . . . . עכשיו, ממש לאחרונה, התחלנו והוספנו מערכת של Gradual Rollout.
  • בנינו אותה In-house, כי ה-Gradual Rollout של היום יותר בנוי ל-Use-case הזה, כמו שאמרתי, של Facebook - כשיש לך סגמנטציה ומלא משתמשים - ופחות למקרה שאני רוצה, ללקוח Enterprise מסויים, שהוא יהיה ב-Stage X ב-Deployment, כי אני יודע שהוא פחות Tolerant לבעיות.
    • ואנחנו באמת פורשים בשלבים - כאשר אתה מתחיל יותר עם ה-Early Adapters - שאתה גם מסכם איתם שהם יחשפו ראשונים והם רוצים לקבל את הדברים כמה שיותר מהר
    • ומגדילים את החשיפה כשאנחנו פוגשים, נגיד, את ה-Enterprise, טיפה יותר מאוחר - וגם אצלם מחליטים מי יהיה ה-Early Adapter בתוך ה-Enterprise, כי אנחנו יודעים גם בתוכו לעשות את ה-Gradual Rollout.
  • וזה ממש משהו שהכנסנו, יחסית, בחצי שנה האחרונה - וממשיכים לשפר ולנטר את זה.

(רן) אוקיי, אז אלו פתרונות יחסית מוצריים, או “Biz-Dev-יים” נקרא לזה - אבל בוא נדבר רגע על פתרונות טכנולוגיים.
הקמתם, בעצם, מערכת פנימית שקראתם לה . . . .
(רן) אז בוא - ספר לנו עליה.
  • (איתן) אז אני אספר רגע על המוטיבציה - אנחנו מאמינים מאוד ב-TDD, הרבה Coverage בטסטים
    • אבל בסופו של דבר אתה עדיין מוצא את עצמך עם רגרסיות ב-Production ו-Crisis-ים . . .
    • והתחלנו לתחקר למה זה קורה.
  • עברנו ממש על . . . אמרנו “בואו נסתכל על השלושה חודשים האחרונים”, על כל הבאגים שהוגדרו כ-On-call, זאת אומרת שהגיעו ב-Production ויצרו Stop the work וצריך עכשיו לתקן אותם . . . .
(אורי) אז זה קרה כי הרגשתם שיש תקופה שבה זה קורה יותר?
  • (איתן) כן - וגם כי כמות ה-User-ים שלנו גדלה פי-2 כל שנה - אז כשיש לך 5-10 User-ים ה-On-call פחות חווה את המשמעות של שלושה אנשים שמתקשרים.
    • כשפתאום 50 אנשים מתקשרים שהם לא מצליחים לעבוד, ואז 100 אנשים בו-זמנית - אז גם העוצמה של ה-On-call הופכת להיות . . . .
    • בעצם, ההגדרה של ה-On-call לא הייתה קיימת בשנתיים-שלוש הראשונות שלנו - זה התחיל רק כשבאמת הגענו למצב שאתה אומר . . . On-call אומר שמישהו צריך לעצור ולהסתכל על זה, כי זה מונע ממישהו לעשות את העבודה שלו, או יותר ממישהו (אחד)
      • אבל אפילו מישהו אחד אצלנו זה מספיק.
  • עשינו תחקור, ראינו שהיו קצת Crisis-ים, ראינו שזה קרה יותר מדי ואמרנו “בואו ננסה להבין למה”.
    • אנחנו עובדים Data-Driven בחשיבה.
(רן) אז אמרתם ללקוח “אבל הכל טסטים ירוקים! מה אתה רוצה ממני?”
(אורי) אצלי זה עובד!”
  • (איתן) בדיוק . . . .
  • אז ממש עשינו קטיגוריות לסיבות של למה זה קרה - לפעמים זה Missing Test, לפעמים זה ש-QA שפספס, לפעמים זה . . . לא יודע, סתם “צעירות”, נקרא לזה.
  • אבל ראינו שאחת מהסיבות שחוזרות על עצמן זה . . . .
(אורי) “QA פספס” זו הסיבה הכי . . . . זה ה”עלה תאנה” הכי גדול שיש
  • (איתן) זה גם מעט מאוד ממה שאתה מחשיב, מהסיבות . . . .
(אורי) כן, אבל כאילו . . . .
(רן) אורי אומר שכשיש ש.ג. שמולו עומד טנק - ואם הוא נותן לו להכנס אז אתה אומר “פאשלה של הש.ג.!” . . . .
  • (איתן) נכון, אז כשאמרנו “QA שפספס” זה היה באמת במעט מאוד מהמקרים, לא בסיטואציות של כסת”ח אלא יותר “שמע, זה היה טריוויאלי, היית אמור לגלות”, אבל זו לא הנקודה.
  • מה שראינו זה שהרבה מאוד מהמקרים היו תחת קטיגוריה של “Edge case” . . . .
    • זאת אומרת שלחשוב לבנות טסט שבודק בדיוק את הקומבינציה של כל המקרים ב-TDD זה לא ריאלי, כי לא עובדים ככה ב-TDD
      • אתה כל פעם מוסיף קצת טסט וקצת קוד
  • וראינו שבסוף יש לנו כל כך הרבה משתמשים במערכת שמגיעים למצבים שונים - כי המערכת היא מאוד עשירה ביכולות שלה, ומה שאפשר לעשות איתה . . . .
    • ולכל לקוח יש את החוקים והדברים ה-Local-יים - ובסוף, הקומבינציה של מה שהוא עושה היא Edge-case
  • אז אמרנו “אוקיי - איך אפשר להתמודד עם Edge Case-ים?” צריך לנסות לקחת את מה שקורה ב-Production וממש להריץ אותו על מה שקורה לנו . . . .
(רן) זאת אומרת - להקליט . . . . להקליט, ולהריץ בחושך . . .
(אורי) כשאתה לא יכול לעשות . . . נכון? אתה Mission-Critical . . . . אנחנו ב-Outbrain, יכולים לקחת חלק מתנועת ה-Production, להריץ אותה מול גרסא חדשה, לראות שהכל בסדר - ולא יקרה כלום אם נגלה את הבאג בזה. אבל פה, הבריטי לא יגיע לפאב . . .
  • (איתן) בדיוק, זה מה שהתחלתי להגיד . . .
(רן) אז אתה אומר שחלק מתנועת ה-Production אפשר להסיט, אבל חלק מתנועת הרכבות אי אפשר להסיט . . . .
  • (איתן) אז אתה גם, בעצם ב-Canary Deployment, כשאתה מתחיל להכווין חלק או אחוז מה-Traffic שלך ואז לנטר בעיות ולזהות את זה לפני ולעשות Rollback ולהחזיר - זה הסטנדרט, יחסית, שעושים היום בתעשייה.
    • אבל כמו שאמרתי - אצלנו (א) אין מספיק משתמשים לזה, כי אם אני אפנה User אחד או שניים, זה לא יגיע לך ל-Edge cases
    • ואני Mission Critical, שזה בכלל מקשה עלי לעשות את זה.
    • והשילוב של שני הדברים האלה . . .
  • (רן) וגם אם תיהיה לו בעיה - אז אתה בבעיה . . .
  • (איתן) . . . . כן, אחד הדברים שעשינו בתחקור היה להגיד “בואו נגיד שהיה לנו Canary Deployment - איזה מה מה - On-call-ים האלה זה היה פותר?”
    • וראינו ש-5% בערך מה-On-call-ים זה היה פותר . . . אז אמרנו “אוקיי, זה לא הפתרון”.
    • אנחנו צריכים ממש לקחת את מה שקורה ב-Production ולהריץ את זה לפני שזה מגיע ל-Production
    • הנקודה היא שאתה לא רק בודק - לבדוק האם עשית רגרסיה, בדר”כ בשיטות כאלה אתה מסתכל על Error Codes ומנטר משהו מלמעלה, יש “יותר 502 Errors נזרקים” או ש”ה-Performance ניהיה איטי”
  • אצלנו, לפעמים ברגרסיה הפעולה מצליחה - היא פשוט מחזירה תוצאה שהיא קצת שונה . . . .
(אורי) זה אותו הדבר, במקרים כאלה אתה פשוט מסתכל על מטריקות Business-יות כדי לראות . . .
  • (איתן) אבל פה אין מטריקה . . . התוצאה היא למשל, סתם דוגמא בסיסית: יש לנו Manual edit, וה-User מזיז משהו מפה לפה במערכת.
    • התוצאה של איך שה-Manual Edit נראה היא JSON- של ממש דאטה של לפני ואחרי
    • אם שיניתי משהו בקוד בטעות ופתאום המ-Manual edit נראה אחרת והוא פתאום עשה Outcome אחר ויצר תוצאה אחרת, אז זה ממש להשוות את התוכן של ה-JSON ולעשות ממש השוואה ברמת הדאטה
    • זה כבר משהו שהוא לא מטריקות כל כך שאתה יכול לנטר - וזה הרבה מהבעיות שהיו לנו.
      • שמישהו הכניס איזשהו שינוי בקוד והתוצאה הייתה שה-APIs התנהגו שונה . . . .
      • אז אני ממש רוצה לבדוק את את ה-APIs
    • כך שהבדיקה היא לא Bit-wise או Stream-wise, כי יש לנו Unique IDs שנוצרים אז מן הסתם אלו דברים שונים, והשוואה היא בעצמה פונקציה שצריך ממש לכתוב אותה כדי להתאים אותה לסוג האופרציה שאתה רוצה להשוות.
  • (אורי) השוואה של התוצאות . . .
    • (איתן) כן
(רן) זה קצת מזכיר את הנושא של בדיקות של UI - אתה רוצה לעדכן איזשהו מסך ב-Web או מסך באפליקציה ועכשיו אתה רוצה לבדוק: יכול להיות שהגרסא החדשה היא שונה במשהו מהגרסא הקודמת . . . . זה לא אומר שזה באג: שינית גוון או ששינית קצת את המיקום של הכפתור, אבל הכל בסדר. אבל אם באמת תשווה את זה Pixel-by-Pixel אז כמובן שתגלה “שגיאה”, וזה יכול לייצר הרבה מאוד רעש.
  • (איתן) נכון, אני חושב שכאן זה באמת דומה יותר לבדיקות של APIs - אתה רוצה להשוות API, אבל כן מותר לך לשנות, ה-API לא מחזיר בדיוק את אותו ה-JSON, יש אלמנטים שהם שונים כי הם Generated כחלק מה . . .
(אורי) ברמת השדות שחוזרים?
  • (איתן) למשל, או שאם הוספתי מטריקה או סטטיסטיקה חדשה, שלא הייתה קיימת, וכחלק מהפעולה גם חוזרות סטטיסטיקות.
    • אז במה שהוקלט ב-Production אין את הסטטיסטיקה החדשה הזו שעכשיו הוספתי, ועכשיו הוספתי חדשה - אני צריך לדעת להשוות ולהבין שיש דברים שהם New וזה בסדר, לעומת רגרסיה.
    • בסוף, חשוב לזהות פה את הרגרסיות.
  • אז המוטיבציה הייתה שאנחנו בעצם מקליטים את מה שקורה ב-Production - אני עוד מעט אסביר איך - ואז אנחנו יכולים “לנגן” את הכל על הקוד, לוקאלית אצל מפתח על המחשב, לנגן את זה ב-Jenkins כחלק מה-CI, ולקבל ממש טבלת Regression שהוא נותן לכל הקלטה, עם Diff כזה של “הכל בסדר” או אם יש רגרסיה או Exception או Whatever שהשתנה.
(אורי) ועל זה צריך לעבור בנאדם? או שהוא אומר לך בסוף תוצאה?
  • (איתן) בסוף הוא אומר לך, מן הסתם, “טוב” או “לא טוב”, כלומר Equal או Different . . . .
    • אם זה Equal אז הכל טוב, אם זה Different אז בנאדם צריך להסתכל על ההבדלים ולהגיד “זה בסדר, כי זה בדיוק מה שעכשיו הכנסתי, זה ה-Difference שאני מצפה לראות”.
    • כי בסוף אנחנו מכניסים שינויים אז יהיו לנו שוני לעומת מה שהוקלט ב-Production.
    • אבל אם הוא לא עשה שינוי ופתאום הוא רואה שההקלטות משתנות לו במקום אחר אז הוא . . . מן הסתם הוא יבין שזה לא בסדר.

(אורי) אז להבדיל מ-TDD, שבו אנחנו כותבים את התוצאה המצופה בטסט שלנו עוד לפני שאנחנו לפעמים בכלל כותבים את הקוד, אנחנו קודם כותבים התוצאה המצופה . . . .
  • (איתן) אני אחד מהצדיקים, כן . . . .
(אורי) . . . אבל פה, אין לך את היכולת ממש להגיד מה הולכת להיות התוצאה המצופה - אתה תמיד תצטרך להסתכל על התוצאות וואז להגיד “אוקיי, זה בסדר וזה בסדר . . . . זה מה שציפיתי” . . . .
  • (איתן) לא בדיוק - מבחינתי, הנחת היסוד פה היא ש-Production הוא בסדר, ולכן התוצאה שהוקלטה ב-Production זה מה שאני מצפה שיקרה . . . .
(אורי) אבל עכשיו אתה מכניס גרסא חדשה . . .
  • (איתן) אז כן - אם עשיתי שינוי והוא לא כזה “Behind the scenes” ולא באמת אמור לשנות את ה-API עצמו
    • ברוב השינויים שאנחנו עושים אנחנו לא משנים את ה-API אלא אני מוסיף יכולת חדשה, וכתוצאה מזה נוגע קצת בקוד פה, עושה קצת Refactor פה, דברים כאלה . . .
(אורי) אבל עכשיו, כשתצא מה-Replay - יהיה Diff?
  • (איתן) רק אם תכננתי שיהיה Diff . . .
(אורי) אבל אם תכננת את זה, המערכת טסטים לא יודעת שתיכננת את זה . . . . להבדיל מ-TDD, שבו אתה משנה את מערכת הטסט עוד לפני.
  • (איתן) נכון, אז פה אתה תראה את ה-Diff הזה, המערכת תודיע לך שיש Diff-ים, ממש תראה לך איפה יש הבדלים
  • ואז אתה צריך להסתכל על זה ולראות האם זה Diff שהתכוונת אליו או לא התכוונת אליו.
(אורי) וכמה פעמים יש באג - זאת אומרת, טעות אנוש - מישהו אומר “כן, זה מה שהיה צריך להיות” ודה-פקטו זה לא היה צריך להיות? כי זו טעות-אנוש . . . .
  • (איתן) אתה מתכוון שהוא ראה את ההבדל ו . . . .
(אורי) הוא ראה את ההבדל, המערכת הציפה את ההבדל - ובנאדם, בעין שלו, הסתכל על זה, ראה שיש 15 הבדלים ואולי לא מתעמק בכל אחד, ובשביעי הוא אמר שככה זה צריך להיות . . . .
(רן) בסדר, כל עוד אתה שם לו את זה מול העיניים . . .
  • (איתן) אין לי סטטיסטיקה לזה.
  • אני יכול להגיד הפוך - אני יכול להגיד ולראות בכמה הורדנו את הרגרסיות כתוצאה מהדברים האלה.
    • כמה פעמים אנשים באו אלי, אחרי ששחררנו את זה, ואמרו “וואו, איך זה שינה לי את העולם, זה פשוט גילה לי את הבעיות שברור שהן היו הופכות להיות On-call”
    • כי הכל עובר עם הטסטים וזה טוב ויפה - אבל הנה, יצרתי פה רגרסיה שבכלל לא . . .
(רן) במידה מסויימת, כשיש פחות False-Positive אז אתה פחות תקבל את הדברים האלה . . . אם על כל דבר המערכת מתריעה, אז בסופו של דבר אנשים כבר, אתה יודע, “זאב-זאב” . . . הם כבר לא ישימו לב לזה. אם במערכת, רמת הרגישות שלה היא נמוכה יותר, ובאמת מתריעה בדר”כ על דברים שהם נכונים, מן הסתם תקבל פחות . . .
  • (איתן) אנחנו מתייחסים לזה היום . . . אם יש התרעה אז אין כזה דבר להכניס בלי להסביר למה זה, למה אתה מכניס.
  • אתה חייב לעבור על זה, וכמעט תמיד זה מגלה באמת בעיה.

(רן) אני חושב על בעיות דומות בעולם של Data - כשאתה רוצה, למשל, לשנות משהו בסכמה של Database או באיזשהו Pipeline או איזשהו Processing של Data - הרבה פעמים לבעיות האלה, מאוד קשה לעשות להן Revert, אם יש לך באג, מאוד קשה לעשות Revert לסיפור הזה . . . אתה יודע, זה לא כמו קוד שאתה פורש ואז גילית באג אז אתה עושה Roll-back או Roll-forward אבל זה מהר מסתדר - לא, פתאום גילית שכבר יומיים יש לך Data לא נכון . . . .מה תעשה? עכשיו אתה צריך לתקן את ה-Data.
אז באגים ב-Data זה הרבה פעמים באגים שהם מאוד קשים להתמודדות - וגישה כזאת, אני גם ראיתי אותה קוראת שם, של לבוא ולעשות איזשהו מנגנון של “הקלטה והשמעה מחדש”. אבל שם יש בעיה של, זאת אומרת, שה-Scale הוא לא טריוויאלי . . . יש בדר”כ עלויות מאוד גבוהות, להקים Infrastructure, להקים Cluster נוסף של Spark של אלף או אלפיים Node-ים זה יקר . . . . אם אתה עושה את זה רק לצורך הטסטים אז זה לא כל כך פרקטי.
אז שם, תיאורטית, למרות שזה נשמע לכאורה מאוד פשוט - פרקטית, הגישה הזאת מאוד מאוד יקרה.
  • (איתן) עכשיו, מה שבכל זאת ייחודי באיך שבנינו את זה זה שיש הרבה יכולות להקליט דברים, אבל יש פחות יכולות “לנגן” דברים
  • כי בסוף, כשאתה מנגן משהו אז אתה תלוי ב-State קיצוני של מה שקורה - ה-End-point הזה יכול לקרוא ל-End-point אחרים ויכול לקרוא ל-Database ויכול לקרוא בכלל ל-URL-ים באינטרנט . . .
  • וכשאתה מנגן את זה לוקאלית, אתה רוצה לוודא שאתה חי באותם “תנאי מגרש” . . . . אין לי את ה-Database באותו State וכל הדברים האלה.
  • אז קצת חיפשתי באינטרנט, ולא מצאתי פתרונות קיימים - רוב הפתרונות זה ”בוא נקליט את ה-Traffic ונדע לשלוח לך את זה לסביבה אחרת”
    • אבל, ברגע שזה ככה, ה- State הולך לאיבוד, של מה שקורה מסביבך.
(אורי) בעניין הזה, רציתי לשאול - כל כמה זמן אתם מקליטים?
  • (איתן) אנחנו מקליטים כל פעולה . . .
  • יש פעולות שעכשיו הן Sampling, כי נגיד שזה קורה בתדירות מאוד גבוהה, אבל אם הן זרקו שגיאה אז אנחנו אוטומטית מדליקים אחד והופכים אותו להיות חלק מה-Sample.
  • מה שאנחנו עושים בהקלטה - בעצם בנינו Open Source Framework ב-Python, אנחנו עכשיו בדיוק ב-TS,JS port שלו, שעושים סוג של אינסטרומנטציה,
    • ממש צריך לסמן בקוד, באמצעות Decorator-ים ב-Python, מה מבחינתך זה Input-ים ומה זה Output-ים של הפעולה.
    • ומה שקורה זה שכשאנחנו ב-Production, אנחנו עושים Intercept ל-Input-ים ומקליטים אותם - זאת אומרת, נניח שיש לי קריאה ל-Database . . . .
(רן) רגע - מה זאת אומרת “מה זה Input-ים”? ה-Input זה הפרמטר לפונקציה וה-Output זה מה שהיא מחזירה . . .
  • (איתן) כן, אבל אם האופרציה עצמה קוראת לדברים באמצע?
    • כמו שאמרתי - אם היא פונה ל-Database, אם היא פונה לדברים חיצוניים, אז עכשיו תקבל Input-ים שאם תנגן את הקוד מחדש, תראה שמישהו מנסה לפנות ל-Database - ואין לך את ה-Database הזה, אז אתה צריך . . .
(רן) אתה מנסה למדל גם את ה-Side effects וגם את התלויות ה-Implicit . . . .
  • (איתן) נכון, בסוף זה Sandbox . . . אתה מריץ את ההקלטה, וזה רץ על המחשב שלי, לוקאלית, ולא תלוי בשום גורם חיצוני, וזה משחזר בדיוק את מה שקרה ב-Production.
(אורי) אבל אתה תריץ את מה שרץ לפני חמש דקות - או משהו שהוקלט לפני יומיים?
  • (איתן) אז בדר”כ אנחנו מריצים Random-ית מהשבועיים האחרונים, אז אתה יכול איך שאתה רוצה.
  • למשל, אחד השימושים הנוספים זה שבכל פעם שעף לנו Error ב-Production, וזה מגיע ל-SENTRY, אנחנו מוסיפים ל-SENTRY את ה-Recording ID.
    • זה היה Side-effect שלא תכננו אותו בכלל, אבל עכשיו כשיש שגיאה אז זה לא “לך תביא לי שחזור”, “לך תעשה לי . .” - זה Copy-Paste של ה-ID הזה וזה מריץ את זה לוקאלית.
    • זה אחד הדברים ששיפרו את הפרודוקטיביות של המפתחים בטירוף
    • וזה עדיין - כל כמה ימים מישהו בא אלי ואומר “פעם הייתי צריך לבקש שחזור ולחפש - עכשיו אני עושה Play Recording וזהו”, פותר שלושה באגים ביום במקום אחד בחמישה ימים עד שאני מצליח לשחזר אותו.
(אורי) מתי יש לו זמן לכתוב באגים? . . . .
  • (איתן) זה תמיד יש . . . אתה מפנה לו זמן לכתוב באגים.
  • אבל כשאנחנו עושים Interception, אנחנו ממש מסמנים על הפונקציה - יש לי פונקציה שניגשת ל-Database, אז אני אסמן עליה שהיא Input
    • ומה שקורה זה שאנחנו נקליט את הפרמטרים שפנו, בתור Query - זה ה-Key.
    • וה-Result זה ה-Value.
  • ואז בתוך ההקלטה, זה ממש מכיל Dictionary של Keys כאלה, של פניות לכל מיני Input-ים ואת ה-Values שחזרו.
    • ואז כשאתה מריץ את זה לוקאלית, אז הקוד שלך אמור לייצר את אותו ה-Query ל-Database, ולכן להחזיר את אותו הדבר.
    • ואם הוא לא - אז פתאום יעוף Exception ב-Recording . . . אם שינית משהו, למשל, ולא התווכנת, אז פתאום ב-Recording לא יהיה איך לשלוף את ה-Data שהיה ב-Production ותקבל No such Key Error, או Whatever.
  • החסרון הוא שאם באמת שינית בכוונה ואתה באמת רוצה לעשות Query חדש, אז ההקלטה כבר לא כל כך רלוונטית, כשתעשה מניפולציה בזמן ההקלטה.

(רן) אז באמת רציתי לשאול על המודולריות של מערכת כזאת, כי זה נשמע כאילו יש לך איזושהי קופסא שחורה ואתה מקליט את כולה - אם כשמשתנה רכיב אחד קטן בתוך הקופסא הזאת, האם זה עושה מיד invalidation לכל מה שהקלטת? . . .
  • (איתן) תראה, Input-ים זו פנייה לעולם החיצון, הפניות שלך לעולם החיצון שמחוץ ל-Service . . .
  • כשאתה עושה שינוי, אתה לא נוטה לשנות את העולם החיצון, כי בעולם החיצון . . . אתה לא נגעת בו עכשיו, בחלק מהדברים האלה.
  • אז רוב הדברים האלה הם בסוף לוקאליים ל-Service, והם גם לא צריכים עכשיו סביבה שלמה של כל ה-Service-ים כדי לנגן את ההקלטה
    • כל Service אוטונומית נבדק . . . .
(רן) הבנתי - זאת אומרת שלכל Service יש הקלטות משלו?
  • (איתן) נכון, ממש כל End-point מוקלט והוא Encapsulated, ועכשיו אני יכול להריץ אותו
    • אני מריץ 500 הקלטות של ה-End-point הזה, ולא צריך שום Data חיצוני ושם דבר.
  • כמובן שאני צריך לשים את ה-Interceptor-ים במקום הנכון ולא לפספס דברים.
    • למשל - יש לנו התנהגות שתלויה ב-Environment variables ושכחנו לעשות Interception לזה והרצתי לוקאלית, וה-Enviroment שלי על המחשב לא כמו ב-Production, אז הקוד שם של ה-If . . . .
    • לא הבנתי למה אצלי זה מתנהג כמו X ו-Y ו . . .
(רן) רגע, יש יותר כייפי - תלוי בכמה מקום יש על הדיסק, תלוי באילו עוד תהליכים יש, יש כל מיני דברים כאלה . . .
  • (איתן) נכון, לכן אתה מגדיר את ה-Environment variable גם כ- Input שאתה צריך לעשות לו Interception, למשל בדוגמא הזאת.

(רן) יש לזה עלות משמעותית? להקלטות, לעלות בזמן פיתוח, לכל מיני עלויות נוספות שאולי לא לקחנו אותן בחשבון? או שאולי . . .
  • (איתן) עלות הפיתוח זו בניית התשתית - זו עלות . . .
(רן) כן, זו עלות הפיתוח - האנוטציות (Annotations), אולי יש באג, צריך לחשוב ולתקן . . . .
  • (איתן) בהתחלה היה יותר . . . . בחודשיים הראשונים, הזמן שאתה צריך לעשות את האינטרציה.
    • נגיד, אחרי שבנינו את ה-Framework עצמו - להתחיל לעשות לו אינטרציה
  • אז בהתחלה יש הרבה נפילות False כאלה, שהוא לא מצליח לשחזר בדיוק את ההרצה ויש כל מיני דברים עד שאתה מזהה בדיוק את כל המקומות שפספסת ב-Interception.
  • אבל ב-Day-to-day אנחנו לא . . .אתה לא מוסיף יותר מדי Inputs חדשים, זה קורה אחת-לחודש, שפתאום מישהו שאל שאלה . . . .
    • אז בהקשר הזה - לא.
  • העלויות הן יחסית זניחות, אנחנו שומרים את הכל ב-S3 עם Life cycle של שלושה חודשים . . .
    • וזה שטויות, זה זניח
  • גם התשתית בעצם שומרת את זה ל-S3 באופן א-סינכרוני, כדי שזה לא יפגע ה-Latency של הפעולה, אז זה מקליט וברקע זה ב-Thread-ים, שולח את זה ל-S3.
    • ואתה יודע - S3 זה לא באמת עולה הרבה
    • כמובן שזה לא מתאים ל-Scale - להקליט כל דבר ב-Scale של מיליון פעולות בשנייה - שם צריך להגדיר Sampling, אז אתה תומך ב-Sampling.
  • יש לזה הרבה דברים מובנים כדי לתמוך בכל מני סוגים שונים של Interception-ים של Input-ים שונים.
  • ובסוף זה הכל Open source ב-Python . . . .

(רן) אני גם יכול לראות איך זה, מעבר ללמצוא רגרסיות ומעבר ללמצוא באגים - איך זה יכול לעזור לך לשפר את הקוד, במובן הזה שאתה עולה ככה על Smell-ים, אתה עולה ככה על פונקציה שיש לה הרבה מאוד תלויות ואתה מבין שיש פה איזושהי בעיתיות, יש פה איזושהי פונקציה שעושה יותר מדי דברים, ואולי נכון יותר לפרק את זה ולעשות איזושהי מודולורזציה. אם אתה רואה שיש הרבה פונקציות שתלויות באותו הדבר, אז יכול להיות שיש פה מקום לייצר איזשהו Service . . . . זה מציף הרבה דברים שאולי קודם הם היו Implicit ומי שמכיר ממש טוב את הקוד יודע אתה זה, אבל בנאדם חדש שנכנס פנימה, עם עיניים חדשות שנכנסות פנימה, הוא לא היה מכיר את זה - אבל עכשיו, כשאתה רק מסתכל על האנוטציות אז אתה יכול מיד לראות את זה.
  • (איתן) כן, זו נקודה מעניינת
  • אחד הדברים, עוד Side-effect שראינו, הוא שבעצם נקטנו בגישה פרו-אקטיבית של תיקון בעיות -
    • להסתכל על SENTRY בלי שפותחים לנו Support cases, ולהתחיל לזהות את ה-Issue-יים ה-Repetitive-יים ולהתחיל לפתור אותם.
    • אז עכשיו יש לנו Recording ID ואני יכול להריץ את זה - אני רואה “הנה הבעיה!” ואני מתקן
      • אבל אז אני אומר “רגע - בעצם, אולי יש לי עוד דוגמאות של הבעיה הזאת, בואו נבדוק שתיקנתי את כולן”.
    • אז מה שאנחנו עושים זה שאנחנו מוסיפים להקלטה גם מטה-דאטה, שמאפשר לבקש “תביא לי את כל ההקלטות שיש להן את הפילטר המסויים על המטה-דאטה”
      • אז למשל זרקנו איזושהי שגיאה, אנחנו שמים את ה-Description של השגיאה כחלק מהמטה-דאטה - ואז זה ממש מסווג את זה
      • “תביא לי את כל ההקלטות שבהן עפה השגיאה הזאת, תריץ לי אותן עכשיו, אחרי שתיקנתי” - ופתאום אתה רואה שהופ! יש פה עוד 50% מה-Case-ים שלא גיליתי בתיקון הזה, ספציפית . . .
      • (אורי) זה לא תפס בתיקון . . . . בעצם לא תיקנתי.
      • (איתן) נכון - ואז אתה יכול לתקן אותם
    • ואתה יכול להוציא מטריקות, לראות כמה כשלונות יש יש לי בכל End-point, וכל מיני מידעים לפי איזה סוג וכל מיני דברים.
  • אבל מטה-דאטה משמש לא רק כדי לפלטר שגיאות - לפעמים אני אומר אוקיי, אני עכשיו יודע שאתה יכול לפלטר על לקוח מסויים, אתה יכול לפלטר על ממש Properties שהועברו ל-End-point הזה
    • אז אתה אומר, נגיד, שאסטרטגיה מסויימת שהופעלה ב-End-point הזה - אז אני שומר במטה-דאטה איזו אסטרטגיה הופעלה
    • ואז אני יכול להגיד “תביא לי את כל ההקלטות של של האסטרטגיה הזאת” - כי עכשיו נגעתי בקוד של האסטרטגיה הזאת.
    • אז זה לא רק ברמת ה-End-points אלא גם ברמת ה-Properties של הפעולה.
  • כמובן שהכל צריך להיות Light-weight, כי זה לא כל ה-Payload של הפעולה - זה צריך להיות שדות Natives כאלה, שפשוטים לפילטור.

(רן) Tracing אתם עושים גם? [להרחבה - 433 Breaking Down Observability with Nitay Milner]
  • (איתן) כן, אנחנו עושים Tracing . . . .
(רן) זה מתחבר איכשהו, שתי המערכות האלה? . . . .
  • (איתן) לא ממש . . . כלומר, הנקודה היחידה היא באמת ה-Recording ID הזה, שמופיע לנו ב-SENTRY וכו’.
    • זה השימוש המרכזי, הייתי אומר.
(רן) כי אני מניח . . . אני מנחש שלפעמים יש באגים של תזמון. זאת אומרת, כשהכל מהר ואין עומס אז זה עובד טוב, אבל כשיש עומס על איזשהו Service ופתאום זמן התגובה שלו יותר איטי, אז פתאום אתה רואה את הבאג - ולצורך זה Tracing יכול לעזור.
  • (איתן) כן, אצלנו זה פחות ה-Use case. אני יכול להבין למה במערכות אחרות . . .
  • אבל אין ספק שאפשר יהיה להוסיף ל-Tracing - להביא את כל ה-Recording IDs של כל ה-Service-ים לאורך השרשרת, שכרגע קרו
    • ואז להתחיל לנגן נקודה-נקודה
  • עכשיו, במערכת החדשה שאנחנו משחררים, שהיא כולה Serverless-ית, אז היא גם כתובה ב-TypeScript, אז אנחנו עושים Port במערכת הזאת ל-TypeScript
    • כי ראינו כמה זה אפקטיבי, באמת - המערכת היא עוד יותר Mission-Critical, אז אנחנו עוד יותר From Day 1 רוצים לצאת מוכנים עם הכלים
    • ושם באמת יש הרבה Lambda-ות שמפעילות Lambda-ות שמפעילות Lambda-ות . . . . ועוברות דרך SQS וכו’
    • אז שם זה באמת . . . .

(אורי) והרבה פעמים, בגלל שזה SQS, אז דברים יהיו א-סינכרוניים, מן הסתם?
  • (איתן) כן
(אורי) וזה מקשה על Tracing . . .
  • (איתן) נכון, אבל בסופו של דבר אותנו מעניין ממש הכניסה הסינכרונית לפונקציה והיציאה ממנה
    • אם היא קראה לדברים א-סינכרוניים ובסוף חזרה מהם עם איזשהו Input, אז זה יהיה חלק מה-Interception של אותו הדבר, אז . . . .
(רן) אבל אם אתה מקליט רק ברמה . . . נחזור לרגע כמה דקות קודם - אם אתה מקליט ברמה של Service, אז בעצם אתה מפסיד את האינטגרציה . . . זאת אומרת, בדר”כ דברים מעניינים או שגיאות מעניינות מתרחשות כש-Service אחד קורא ל-Service אחר, והוא קורא ל-Service שלישי וכו’.
אז את זה אתה לא מפסיד?
  • (איתן) הרבה פעמים, הבעיה היא בסוף ב-Service השלישי, והוא זה שזורק לי Exception ל-SENTRY שמשהו קרה לא בסדר
    • ולא כל כך מעניין אותי איך הגענו לשם - מעניין אותי מה שבור בקוד הזה.
  • אז נכון - זה לא מרים סביבה מלאה ואז מנגן, כי אז אתה נכנס עוד פעם לאותה הבעיה של איך אתה משחזר את כל הדאטה ומריץ על 10,000 דגימות שונות Random-יות . . . .
(רן) אבל תראה, Scenario שהייתי רואה לא מעט זה שאותו Service שלישי - ה-Maintainer שלו שינה משהו ב-API, ומבחינתו הכל בסדר. הוא עשה והריץ וראה שיש Diff ואמר “אוקיי, זה בדיוק מה שהתכוונתי”. מחר בבוקר, כשמישהו אחר גם ישתמש ב-API שלו ואולי לא מודע לשינוי הזה - לפעמים זה שינוי בסכמה, לפעמים זה שינוי סמנטי שאתה לא יכול לתפוס - פתאום דברים נשברים.
  • (איתן) נכון, זה לא מיועד לזה.
    • זה מיועד לרמת ה-Service שלך, לבדוק שאתה לא יצרת Regression.
    • אז מי שהריץ את ההקלטות והחליט “לא, זה בסדר השינויים האלה” - אז היה צריך לעשות את זה בידיעה.
  • זה לא מבטל את הצורך לעשות ממש טסטים בסביבה שלמה, אבל מאוד מאוד קשה לעשות בכזה Scale וכזו כמות . . .
    • כשאתה מדבר על סביבה אחרת ויש לך הרבה - נגיד Database חיצוני ו-State שאתה תלוי בו - אני בכלל לא חושב שזה אפשרי לעשות את זה ממש טוב.
    • לקחת, נגיד, 10,000 דגימות של לקוחות שונים מפוזרים Random-ית על המרחב ולהריץ את זה איכשהו בסביבה צדדית שהיא . . . כשה-Database כלל לא שומר על התמונה . . .

(רן) אז אני שומע שאתם עכשיו עובדים על קוד פתוח של אותו רכיב . . . .
(רן) חוץ מכם יש עוד משתמשים?
(אורי) איך הוא נקרא?
(רן) Equalizer זה מעניין . . . מה עושה Equalizer? יש סראונד? . . .
  • (איתן) אז בעצם, כשאתה מנגן מחדש, אתה צריך, כדי לבצע את ההשואות, צריך איזשהו Plug-in שאומר איך אני משווה דברים.
  • אז ה-Equalizer אחראי על איזה שלושה-ארבעה Plug-ins שאתה צריך לממש כדי לבצע את הניגון ולבצע את ההשוואה.
(רן) . . . על מנת לעשות את התמרות הפורייה הנדרשות כדי להוריד את הטונים . . .
  • (איתן) נכון
(רן) מעניין . . .
  • (איתן) כן . . . אז בסוף, בשונה מהרבה גישות היום שהן מאוד דומות - שלא מתערבים לך בקוד, אני עושה הכל מבחוץ ואתה רק עושה פה איזה Import - פה זה לא המצב.
    • המצב פה הוא שאתה צריך לשים Decorator-ים במקומות הנכונים
    • ואתה צריך לכתוב Plug-In אם ההשוואה היא לא סופר-טריוויאלית - אז ה-Plug-In-ים שלך יכולים להיות יותר ויותר מורכבים.
    • יש לזה ידע אינטימי . . . מי שכותב את זה - צריך שיהיה לו ידע אינטימי עם ה-Service
    • והרבה פעמים, ה-Service-ם - יש להם כזה Base-class שאתה משתף . . . יש לך איזושהי תבנית חוזרת בהרבה מאוד מה-End-Points שלך.
  • אז אצלנו, נגיד - בסוף יש לנו שני סוגי End-Point - או שזה celery-based או שזה HTTP-Based - והיה מאוד קל לעשות את ה-Interception בצורה שהוא . . . .
(רן) אבל זה לא Black-box, זאת אומרת . . . זה לא Black-box, אתה כן צריך להכיר את ה-Server-ים שלך; מצד שני - זה לא Unit Test - זה לא בודק פונקציות יחידות, זה בודק איזושהי יחידה - קראת לזה “Service”, למרות שאתה תכל’ס יכול גם לבדוק יותר מ-Service אחד, נכון?
  • (איתן) אתה יכול בסוף להחליט לשים Decorator של איפה מתחילה אופרציה בכל מקום בקוד
  • אפשר להגיד שקריאה אחת . . . תיאורטית אתה יכול לעשות את זה ברמת הפונקציה, אבל זו לא המטרה . . .
  • המטרה היא לנגן משהו שהוא יותר גדול.

(רן) טוב, מעניין . . . . שיהי לכם בהצלחה עם הפונקציות Lambda בכל הסיפור הזה, כי שם זה נשמע לי יותר מורכב . . . לבדוק פונקציה לכשלעצמה זה יחסית קל, אבל ברגע שיש לך כמה מאות שעובדות אחת עם השנייה דרך SQS-ים ודברים א-סינכרוניים, זה ניהיה כבר הרבה יותר מורכב. אני מניח ששם זה כבר לא יהיה רק על פונקציה בודדת?
  • (איתן) לא, התשתית הזאת כן תיהיה ברמת הפונקציה הבודדת - יהיו . . .
  • כמובן, יש לנו את הדרכים להרים סביבה שלמה ולהזרים אליה Traffic וכו’ - אבל תמיד ה-Coverage של ה-Edge cases יהיה הרבה יותר קטן בסיפור הזה.
    • ושם גם יש את הטריק של Lambda-ות - מכיוון שאנחנו לא רוצים להתערב עם ה-Latency של הפעולה, ו-Lambda מתחילה ומתה, ואני בסוף צריך לאסוף את כל הדברים בדרך - אז יש פה טריקים של איך אתה בכל זאת שולח את ההקלטה.
    • יש עבודה שצריך במימושים של ה-Abstract Classes האלה, כדי להתאים אותם לסביבה של Lambda-ות, לעומת Flask, לעומת celery, וכו’.
  • יש לנו גם קצת Contributors מבחוץ, ואנחנו מאוד נשמח שאנשים יתרמו וישתמשו בזה ויפיקו את הערך . . . אנחנו באמת מפיקים מזה ערך.

(רן) אני חושב שהאתגרים קיימים בעולם ה-Tracing - אם תסתכל על Design של Jaeger או של של מערכות A-sync אחרות, אתה תראה שהן באו לפתור אתגרים מאוד דומים, של איך לשלוח נגיד, את ה-Trace לפני שה-Service מסיים את החיים שלו, ויש לזה כל מיני סוגים של פתרונות, בין אם זה לשלוח מקומית דרך UDP ואחר כך לאסוף את זה, או כל מיני פתרונות מסוגים אחרים.
(אורי) אני יודע שב-Outbrain עשו Cross-Service Tracing וכו’ . . . הדבר שדומה אולי, קצת, ל-Lambda-ות זה שעשינו את זה גם על עבודות א-סינכרוניות, על קריאות א-סינכרוניות בין ה-Service-ים.
(רן) אתה מוסיף איזושהי Envelope ל-Message, כדי לדעת מה ה-Trace ID.
  • (איתן) אנחנו משתמשים ב-New Relic וכל מיני . . . Lumigo ודברים כאלה
  • אבל בסוף זה בא להראות לך דברים - זה לא נותן לך את היכולת הזאת, של להריץ מחדש, לקבל שחזורים - שזה ה-Added-value פה, זה מה שהתשתית הזו בעצם מיועדת עבורו.
(רן) עכשיו כשאתה אומר, זה נשמע כאילו הגיוני שהם גם יעשו את זה, אבל בסדר . . .
  • (איתן) היו כבר כמה פניות, בעקבות . . . ששמעו אותי מדבר על זה, אז יזמים שרוצים לבנות ממש חברה סביב הנושא
    • אני חושב שאפשר ממש לבנות חברה סביב הסיפור הזה, בסוף אבל צריך . . .
    • אני חושב שזה לא יעבוד בלי הגישה של . . . המפתח צריך לדעת איך להשתמש ב-Framework הזה - ולהשתמש בו, לשים את ה-Interception במקום הנכון.
    • כמובן שאפשר לבוא עם ה-Out-of-the-Box Interception כבר מוכן וכל מיני דברים כאלה, אבל יש דברים אינטימיים שאתה חייב לדעת כדי שזה באמת יצליח לנגן את זה נכון.
(אורי) אם היה לי שקל על כל סטארטאפ שבא ואומר “כן, יש לנו איזשהו פתרון לבעיה בעולם ה-Production” או בעולם כזה או אחר, וכן, בסדר - פתרנו את זה לפני שלוש שנים, או לפני . . . .

(רן) טוב, איתן - אז זה נשמע סופר-מעניין וגם מאתגר. נוסיף את הקישור ל-GitHub, אני מניח, בפודקאסט עצמו [כן]. אני גם מנחש שאתם מחפשים מהנדסים, פה ושם? . . . .
  • (איתן) כן . . . . כמובן, אנחנו צריכים לגייס עוד לפחות איזה 150 איש השנה, שכוללים . . .
(רן) אז ספר קצת על ה-Stack הטכנולוגי - הזכרת ככה קצת, אבל איך בגדול . . . מה עושים בחברה? באילו טכנולוגיות עובדים?
  • אז אנחנו מערכת שכולה Deployed ב-AWS - הכל Cloud-based, אין שום דבר On-Premise.
  • אנחנו באמת עובדים עם מכוון רחב של דברים - מבחינת שפות זה מ-Python ו-TypeScript ו-JavaScript ו-Node.js וכו’.
  • אנחנו עובדים הרבה מאוד עם Lambda-ות וכמובן Kubernetes והכל - זה או Kubernetes או Lambda-ות
  • וכל צוות, או כל מודול - אנחנו עובדים ב-Product teams - יש לו Stack טכנולוגי שרלוונטי אליו
    • יש צוותים שעובדים Pure-Serverless, יש צוותים שעובדים Mix & Match ביניהם, יש צוותים שבעיקר על Kubernetes Pods - הכל תלוי ב- Use case ,כמובן.
  • ובאמת מחפשים אנשים שרוצים מצד אחד לעבוד במשהו שבאמת עושה טוב לעולם - לא כקלישאה אלא באמת לשפר את התחבורה הציבורית והאימפקט של זה, גם על איכות הסביבה, הוא מאוד גדול
    • אני לא זוכר אפילו את המספרים, כמה מאות-מיליונים של Emissions ירדו כתוצאה מהשימוש במערכת שלנו, שמתכננת גם רכבים חשמליים
      • זה אחד האתגרים היום, שאוטובוסים חשמליים הם הרבה יותר קשים לתפעול, וצריך מערכת חכמה לתכנן אותם כדי להיות מסוגל להשתמש בהם בכלל
      • איך אתה טוען אותם, מתי אתה טוען אותם . . . .
    • (רן) בגלל הפסקות הטעינה שנדרשות . . .
      • (איתן) כן - מתי לטעון וכמה Capacity יש לך ואיזה סוג מטען . . . . מלא שאלות שצריך לעשות, שבדיזל אתה פשוט מתדלק ובסוף היום רואה את האוטובוס שוב פעם בתחנת דלק
  • אז יש הרבה אתגרים - גם אלגוריתמיים וגם לבנות מערכת, כמו שאמרנו, Mission-Critical SaaS Platform
  • והאנשים אצלנו עם מוטיבציה גבוהה להפעיל את היכולות שלהם ובאמת לנסות להשפיע על היומיום של כל האנשים ולהעביר אותם לתחבורה ציבורית.
(רן) איפה בישראל?
  • (איתן) אנחנו יושבים ממש במרכז, היום בבניין ToHa, ממש שם בשלום . . . .
  • אני, למשל, מכרתי את האוטו שלי - יש לי אוטובוס מהבית בכפר סבא ממש עד למשרד.
    • מבטיח שלא נגעתי במערכת ודאגתי שזה מה שיקרה אלא גיליתי את זה במקרה . . .
    • אנחנו ממש ב-Hub של תחבורה ציבורית ומעודדים את כולם לבוא עם תחבורה ציבורית ומאוד לא נוטים לבוא במכוניות לעבודה.

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


האזנה נעימה ותודה רבה לעופר פורר על התמלול!
  continue reading

152 פרקים

כל הפרקים

×
 
Loading …

ברוכים הבאים אל Player FM!

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

 

מדריך עזר מהיר