פתרון העברת ממשקים בין גבולות¶
פתרון התרגיל הראשון¶
הקריאה מתחילה בworker, אך המימוש שייך לSTA ולכן התשתית מנתבת אליו את הביצוע. קוד E_NOINTERFACE בדוגמה הוא תוצאה יישומית צפויה של מתודה שהגיעה ליעד. נוכיח הגעה באמצעות ההדפסה מתוך CreateInstance, ולא רק באמצעות קוד שנראה מוכר.
השהיה של הSTA יכולה לעכב גם את שלב הunmarshalling, ולכן לא נניח שכל זמן ההמתנה שייך למתודה עצמה. נפריד בlog בין לפני ההמרה, אחריה, לפני הקריאה ואחריה. תצפית כזאת מגלה באיזה גבול נוצר העיכוב בלי לנחש לפי השורה האחרונה שהודפסה.
פתרון התרגיל השני¶
המסלול החדש נכנס אחרי הצלחת CoMarshalInterThreadInterfaceInStream ולפני CreateThread. הוא קורא לabandon_packet, ואז לCoUninitialize וחוזר. הערך unmarshaled נשאר false, ולכן מתבצע שחרור של נתוני ההעברה לפני שחרור הstream.
אפשר להוסיף למחלקת Probe destructor שמדפיס destroyed. אין לצפות שמספר קריאות AddRef פנימיות של COM יהיה קבוע בין גרסאות. נבדוק את ההתחייבויות שלנו ואת סיום חיי האובייקט, במקום להפוך התנהגות פנימית מקרית למבחן קשיח.
אם נשתמש בפונקציה שצורכת ומשחררת את הstream, נצטרך לשנות גם את הבעלות בצד היוצר. אי אפשר להחליף רק את שם הפונקציה ולהשאיר שחרור נוסף בסוף. טבלת בעלות לכל מסלול הצלחה וכשל היא חלק מהפתרון.
פתרון התרגיל השלישי¶
הלקוח יבחר request ID לפני Start וישמור אותו. השרת יקשר אותו לזהות המאומתת ולתוכן הבקשה, וישמור תוצאה באותה טרנזקציה שבה הפעולה מתחייבת. אחרי timeout הלקוח ידווח מצב לא ידוע ויבצע Query לפי אותו מזהה לאחר חיבור מחדש. הוא לא ייצור אוטומטית מזהה חדש עבור אותה כוונה.
הביטול יהיה בקשה לשינוי מצב, עם תוצאה כגון canceled, already-completed או still-running. קריסה של השרת אינה מבטיחה שפעולה חיצונית בוטלה. אם הפעולה מפעילה מערכת אחרת, גם הגבול הזה צריך חוזה idempotency או התאוששות.
פענוח packet של COM יכול לגרום לתשתית לטעון ולהפעיל קוד של רכיבים. לכן זה אינו parser תמים לקלט כללי. נעביר רק packet שנוצר במסלול מהימן שמתאים למודל ההרשאות שלנו. לנתוני לקוח רגילים נגדיר פורמט מוגבל משלנו ולא נקרא להם interface pointer רק מפני שהם מכילים בתים.