לדלג לתוכן

פתרון שירות הודעות מתאושש

פתרון ראשון

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

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

פתרון שני

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

busctl --user call org.amit.Counter /org/amit/Counter \
  org.amit.Counter1 Add sstt "$old_epoch" request-after-restart 5 0

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

פתרון שלישי

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

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