איך React Bundle שמור ב-Cache שלח נתונים למסד הנתונים הלא נכון
עמדנו בדדליין. צוות ה-backend ביצע מיגרציה ל-API חדש ולמסד נתונים חדש. צוות ה-frontend עדכן משתני סביבה ב-AWS Amplify ודחף את הקוד.
הפריסה הצליחה. סגרנו את הלפטופים. חשבנו שסיימנו.
טעינו.
מהנדס בדק את הלוגים בשרת ה-API הישן. השרת הזה היה אמור להיות כבוי. הוא לא היה. הוא קיבל בקשות אמיתיות של לקוחות וכתב נתונים למסד הנתונים הישן.
במשך שעתיים, נתונים אמיתיים של לקוחות נשלחו למקום הלא נכון.
הנה הסיבה לכך ואיך תיקנו את זה.
הבעיה
אפליקציות React על CDNs כמו AWS Amplify מחליפות משתני סביבה בזמן ה-build. כשמריצים build, ה-bundler מוצא כל משתנה ומחליף אותו במחרוזת קשיחה (hardcoded string).
ה-API URL היה מוטמע פיזית בתוך קובץ ה-JavaScript.
כשביצענו deployment, משתמשים חדשים קיבלו את ה-bundle החדש. אבל משתמשים קיימים עם האפליקציה פתוחה מעולם לא רעננו את הדף. הם המשיכו להריץ את ה-bundle הישן עם ה-URL הישן שמוטמע בתוכו.
מכיוון שהשרת הישן עדיין פעל, הלקוחות האלו קיבלו סטטוס 200 OK. הכל נראה תקין. הכשל היה שקט. שקט הוא סוג הבאג המסוכן ביותר.
הפתרון בשלוש שכבות
בנינו שלוש שכבות כדי להבטיח שזה לא יקרה שוב.
1. Runtime Configuration הפסקנו "לאפות" (baking) URLs לתוך ה-JavaScript bundle. במקום זאת, אנחנו משתמשים בקובץ config.json בתיקיית ה-public. ה-bundler לא נוגע בקובץ הזה. האפליקציה שולפת את הקובץ הזה בזמן ריצה (runtime) לפני שהיא מתרנדרת. זה מבטיח שסשנים חדשים תמיד יקבלו את ה-URL הנכון.
2. WebSocket Notifications קונפיגורציית runtime לא עוזרת למשתמשים עם טאב פתוח. קישרנו את תהליך הפריסה שלנו לשרת ה-WebSocket שלנו. כש-Amplify מסיים build, הוא קורא ל-webhook ב-API שלנו. השרת אז דוחף הודעה לכל הלקוחות המחוברים. אם משתמש נמצא בגרסה ישנה, מופיע באנר שמבקש ממנו לרענן את הדף.
3. Cache Management עדכנו את הגדרות ה-CloudFront שלנו. נקודות כניסה כמו index.html ו-config.json מוגדרות כעת ל-no-cache. זה מבטיח שמשתמשים תמיד ישתמשו בקבצים העדכניים ביותר במקום בגרסאות ישנות מ-CDN edge node.
הלקחים
• קונפיגורציה בזמן הבנייה (Build-time config) היא מלכודת עבור ערכים שמשתנים בין פריסות. • שתיקה מסוכנת יותר מרעש. גרמו למערכות ישנות להיכשל בצורה "רועשת" באמצעות סטטוס 410 Gone. • לחץ של לוחות זמנים שובר תהליכים ידניים. אוטומציה לתהליך ההוצאה משימוש (decommissioning) שלכם. • נתרו את הדברים שאתם מכבים, לא רק את הדברים שאתם מדליקים.
פריסה (Deployment) היא לא רק דחיפת קוד. מדובר לוודא שכל לקוח בסופו של דבר מריץ את הקוד הנכון.
מקור: https://dev.to/sugan_dev/how-a-cached-react-bundle-sent-production-data-to-the-wrong-database-55n9