אופס הכנסתי קונסטריינט

09/11/2023

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

def createPost(g: GraphTraversalSource, slug: String, title: String, publishedAt: String): Vertex =
  g.addV("post")
    .property("slug", slug)
    .property("title", title)
    .property("publishedAt", LocalDateTime.parse(publishedAt, formatter))
    .next()

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

גרמלין היא שפת שאילתות ואפשר להשתמש בה כדי לתשאל בסיסי נתונים מרוחקים (למשל neptune שרץ בענן של AWS או קוסמוס שרץ באז'ור או ארקייד דיבי שרץ על מכונה שלכם), ובנוסף כדי לגשת לבסיסי נתונים בזיכרון שרצים באותו JVM כמו התוכנית.

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

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

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