דילוג לתוכן הראשי
שיתוף 6 דק׳ קריאה

מ-MVP לפרודקשן חלק ב'. טיפים לקוד קלוד טור #18 מאת אלכס

Commodore 64
רטרו 8 ביט בדם שלי (עודכן)4 צפיות

הי חברים יקרים 😍 גם השבוע הטיפים באים מהניסיון שלי, ורק מהניסיון שלי. ברשת תמצאו אינספור "תעשה ככה וככה", אבל אני כותב אחרי בערך שנה עם קלוד קוד ולא מעט פרויקטים מעניינים שבניתי איתו. בטור שעבר דיברנו על הרגע שבו הצעצוע שלנו  צריך להפוך למוצר. עברנו על שבע נפילות: ה-Happy Path (המסלול הבטוח והצפוי לכאורה) , תהליך שנופל בלי שאף אחד יודע, הדאטה וההודעות הכפולות, סודות בתוך הקוד, כלים שמושלמים ל-MVP אבל לא ל-Scale, השרת ש"פשוט רץ" ו-Main שכבר לא ארגז חול. הפילוסופיה הייתה פשוטה: MVP שואל "האם זה עובד?", פרודקשן שואל "מה קורה כשזה לא עובד?".

אז תכלס... הנושא הזה גדול מכדי להיכנס לטור אחד. היום ממשיכים בחלק ב' (טם-טם-טם 🔔) MVP לפרודקשן חלק ב'!

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

נפילה שמינית: השרת הוא לא המחשב שלכם
============================================

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

  • משתני סביבה. בטור הקודם אמרתי שהקובץ .env נכנס ל-.gitignore ולא עולה ל-Git. וזה נכון! אבל המשמעות היא שהשרת לא מקבל אותו אוטומטית, וצריך להגדיר את המפתחות גם שם. 

  • גרסאות. אצלכם רץ Python או Node בגרסה אחת, ועל השרת בגרסה אחרת. מה שעבד פה לא בהכרח יעבוד שם. צריכים לוודא שיש אותם גירסאות !!! סופר חשוב ! 

  • אזור זמן של ישראל מול איזור זמן של השרת . הרבה שרתים מוגדרים לפי UTC ולא לפי שעון ישראל. ו-Cron, למשל, רץ לפי השעון של השרת. תחשבו על פרויקט כמו פרויקט הווצאפ שלי, שבו כל מנוי בוחר באיזו שעה לקבל את ההודעה. פה כדאי לוודא שהשעה שהמנוי בחר היא באמת השעה שבה ההודעה יוצאת...

אז לפני שעולים, שווה לבקש מקלוד לעשות השוואה:

Compare my local environment with the production server: versions, environment variables, timezone and file paths. List anything that could behave differently

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

נפילה תשיעית: שירות חיצוני שלא עונה (או עונה לאט)
=====================================================

כמעט כל פרויקט שלי מדבר עם שירותים חיצוניים: Green API, Resend, אתרים שעושים להם Scraping ועוד. ב-MVP הם תמיד עונים ותמיד יש תשובה מהירה. בפרודקשן לפעמים לא.

שלושה דברים ששווה לבדוק:

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

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

  • מגבלות קצב (Rate Limits). הרבה שירותים מגבילים כמה קריאות מותר לשלוח בפרק זמן מסוים. עם 10 משתמשים לא תרגישו את זה. עם אלפים, כנראה שכן.

נפילה עשירית: הוא צעק, מה אתה צועק?
======================================

בטור הקודם אמרתי שתהליך שרץ בלי שמסתכלים עליו חייב לדעת לדווח.. . אבל קיבלתם מייל מ-Resend שמשהו נכשל... ומה עכשיו? מאיפה מתחילים לחפש?

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

שני דברים לשים לב אליהם:

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

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

Add clear logging to the main processes so I can understand what happened when something fails

נפילה אחת עשרה: לשנות את הדאטהבייס כשיש עליו אנשים אמיתיים
===================================================================

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

אז לפני כל שינוי מבנה (Schema) במסד חי:

  • גיבוי. תמיד. כמו לשמור משחק לפני הבוס של השלב 🙂 זוכרים שאני חסיד ענק של משחקי ארקייד בסגנון Double Dragon ?

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

  • לדעת מראש איך חוזרים אחורה אם משהו לא הסתדר. ולא תמיד עובד RollBack במצבים מסויימים. 

וכן, גם את זה קלוד יודע לעשות מעולה:

Before we change the database schema, create a backup, test the migration on a copy of the data, and write me a rollback plan

נפילה שתים עשרה: מה שטס עם 10 זוחל עם 20 אלף
=====================================================

עם 10 מנויים כל שאילתה מהירה, לא משנה איך כתבתם אותה. כשהתוכנית היא להגיע לאלפים, כמו ה-20K שאני מכוון אליהם בפרויקט הווצאפ, אותה שאילתה בדיוק יכולה פתאום לקחת הרבה יותר זמן. אחד הפתרונות הנפוצים הוא אינדקס (Index). תחשבו על אינדקס בסוף ספר: במקום לדפדף עמוד אחרי עמוד, הולכים ישר למקום הנכון. במסד נתונים כמו PostgreSQL אינדקס על העמודה הנכונה יכול לעשות הבדל ענק.

לא צריך לנחש איפה . אפשר פשוט לשאול את קלודי שלנו :

Which queries in this project will get slow when the tables grow to 20,000 users? Suggest indexes and explain why each one helps

נפילה שלוש עשרה: הגרסה החדשה שברה הכל. מה עושים?
========================================================

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

עכשיו יש שתי דרכים להגיב:

  • להתחיל לדבג בלחץ, ישר על השרת החי, כשכל דקה שעוברת המשתמשים מרגישים את זה.

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

תכלס, הדרך השנייה כמעט תמיד עדיפה. קוראים לזה Rollback, כלומר חזרה לגרסה היציבה האחרונה (או לגרסת בייסליין שאתם יודעים שעובדת). זוכרים שבטור #11 אמרתי ש-Git הוא מערכת Save Game לפרויקט? אז Rollback זה בדיוק לטעון את השמירה האחרונה לפני הבוס שהרג אתכם 😄

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

והנקודה הכי חשובה: את התוכנית הזאת עושים מראש. כן כן, מראש! לא בשבע בבוקר כשהכל בוער. ככה כשזה קורה, לא מאלתרים, רק מבצעים. שווה לרשום אותה בקובץ בפרויקט, למשל DEPLOY.md, בדיוק כמו קבצי ה-Claude Notes מטור #3. 

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

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

באהבה, אלכס! 🥰


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

https://8bitretro.tech/

תגובות

לקריאה מהירה: מ-MVP לפרודקשן חלק ב'. טיפים לקוד קלוד טור #18 מאת אלכס

תוכן הפוסט

הי חברים יקרים 😍 גם השבוע הטיפים באים מהניסיון שלי, ורק מהניסיון שלי. ברשת תמצאו אינספור "תעשה ככה וככה", אבל אני כותב אחרי בערך שנה עם קלוד קוד ולא מעט פרויקטים מעניינים שבניתי איתו. בטור שעבר דיברנו על הרגע שבו הצעצוע שלנו  צריך להפוך למוצר. עברנו על שבע נפילות: ה-Happy Path (המסלול הבטוח והצפוי לכאורה) , תהליך שנופל בלי שאף אחד יודע, הדאטה וההודעות הכפולות, סודות בתוך הקוד, כלים שמושלמים ל-MVP אבל לא ל-Scale, השרת ש"פשוט רץ" ו-Main שכבר לא ארגז חול. הפילוסופיה הייתה פשוטה: MVP שואל "האם זה עובד?", פרודקשן שואל "מה קורה כשזה לא עובד?".

אז תכלס... הנושא הזה גדול מכדי להיכנס לטור אחד. היום ממשיכים בחלק ב' (טם-טם-טם 🔔) MVP לפרודקשן חלק ב'!

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

נפילה שמינית: השרת הוא לא המחשב שלכם
============================================

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

  • משתני סביבה. בטור הקודם אמרתי שהקובץ .env נכנס ל-.gitignore ולא עולה ל-Git. וזה נכון! אבל המשמעות היא שהשרת לא מקבל אותו אוטומטית, וצריך להגדיר את המפתחות גם שם. 

  • גרסאות. אצלכם רץ Python או Node בגרסה אחת, ועל השרת בגרסה אחרת. מה שעבד פה לא בהכרח יעבוד שם. צריכים לוודא שיש אותם גירסאות !!! סופר חשוב ! 

  • אזור זמן של ישראל מול איזור זמן של השרת . הרבה שרתים מוגדרים לפי UTC ולא לפי שעון ישראל. ו-Cron, למשל, רץ לפי השעון של השרת. תחשבו על פרויקט כמו פרויקט הווצאפ שלי, שבו כל מנוי בוחר באיזו שעה לקבל את ההודעה. פה כדאי לוודא שהשעה שהמנוי בחר היא באמת השעה שבה ההודעה יוצאת...

אז לפני שעולים, שווה לבקש מקלוד לעשות השוואה:

Compare my local environment with the production server: versions, environment variables, timezone and file paths. List anything that could behave differently

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

נפילה תשיעית: שירות חיצוני שלא עונה (או עונה לאט)
=====================================================

כמעט כל פרויקט שלי מדבר עם שירותים חיצוניים: Green API, Resend, אתרים שעושים להם Scraping ועוד. ב-MVP הם תמיד עונים ותמיד יש תשובה מהירה. בפרודקשן לפעמים לא.

שלושה דברים ששווה לבדוק:

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

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

  • מגבלות קצב (Rate Limits). הרבה שירותים מגבילים כמה קריאות מותר לשלוח בפרק זמן מסוים. עם 10 משתמשים לא תרגישו את זה. עם אלפים, כנראה שכן.

נפילה עשירית: הוא צעק, מה אתה צועק?
======================================

בטור הקודם אמרתי שתהליך שרץ בלי שמסתכלים עליו חייב לדעת לדווח.. . אבל קיבלתם מייל מ-Resend שמשהו נכשל... ומה עכשיו? מאיפה מתחילים לחפש?

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

שני דברים לשים לב אליהם:

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

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

Add clear logging to the main processes so I can understand what happened when something fails

נפילה אחת עשרה: לשנות את הדאטהבייס כשיש עליו אנשים אמיתיים
===================================================================

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

אז לפני כל שינוי מבנה (Schema) במסד חי:

  • גיבוי. תמיד. כמו לשמור משחק לפני הבוס של השלב 🙂 זוכרים שאני חסיד ענק של משחקי ארקייד בסגנון Double Dragon ?

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

  • לדעת מראש איך חוזרים אחורה אם משהו לא הסתדר. ולא תמיד עובד RollBack במצבים מסויימים. 

וכן, גם את זה קלוד יודע לעשות מעולה:

Before we change the database schema, create a backup, test the migration on a copy of the data, and write me a rollback plan

נפילה שתים עשרה: מה שטס עם 10 זוחל עם 20 אלף
=====================================================

עם 10 מנויים כל שאילתה מהירה, לא משנה איך כתבתם אותה. כשהתוכנית היא להגיע לאלפים, כמו ה-20K שאני מכוון אליהם בפרויקט הווצאפ, אותה שאילתה בדיוק יכולה פתאום לקחת הרבה יותר זמן. אחד הפתרונות הנפוצים הוא אינדקס (Index). תחשבו על אינדקס בסוף ספר: במקום לדפדף עמוד אחרי עמוד, הולכים ישר למקום הנכון. במסד נתונים כמו PostgreSQL אינדקס על העמודה הנכונה יכול לעשות הבדל ענק.

לא צריך לנחש איפה . אפשר פשוט לשאול את קלודי שלנו :

Which queries in this project will get slow when the tables grow to 20,000 users? Suggest indexes and explain why each one helps

נפילה שלוש עשרה: הגרסה החדשה שברה הכל. מה עושים?
========================================================

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

עכשיו יש שתי דרכים להגיב:

  • להתחיל לדבג בלחץ, ישר על השרת החי, כשכל דקה שעוברת המשתמשים מרגישים את זה.

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

תכלס, הדרך השנייה כמעט תמיד עדיפה. קוראים לזה Rollback, כלומר חזרה לגרסה היציבה האחרונה (או לגרסת בייסליין שאתם יודעים שעובדת). זוכרים שבטור #11 אמרתי ש-Git הוא מערכת Save Game לפרויקט? אז Rollback זה בדיוק לטעון את השמירה האחרונה לפני הבוס שהרג אתכם 😄

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

והנקודה הכי חשובה: את התוכנית הזאת עושים מראש. כן כן, מראש! לא בשבע בבוקר כשהכל בוער. ככה כשזה קורה, לא מאלתרים, רק מבצעים. שווה לרשום אותה בקובץ בפרויקט, למשל DEPLOY.md, בדיוק כמו קבצי ה-Claude Notes מטור #3. 

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

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

באהבה, אלכס! 🥰

=================================================

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

https://8bitretro.tech/

נכתב על ידי Commodore 64