פתרון רשת אסינכרונית ועומס¶
פתרון התרגיל הראשון¶
בלי לקוח תסתיים ההמתנה לקבלה, תישלח בקשת ביטול וננקז את השלמתה. עם לקוח פעיל נצפה להשלמת קבלה ולאחריה להשלמת קריאה עם מידע או סוף זרם, בהתאם למה שהלקוח עשה. עם לקוח ששותק, הקבלה יכולה להצליח משום שלא ביקשנו payload כחלק ממנה, אבל הקריאה תגיע למסלול timeout וביטול.
אם היינו מבקשים מידע בתוך AcceptEx, קבלת החיבור והמתנה למידע ראשון היו חלק מאותה פעולה. לקוח שפתח TCP אך לא שלח מידע יכול לעכב את השלמתה. זאת סיבה להפריד timeout של חיבור מdeadline של בקשת יישום, ולא לספור כל socket שמחובר כאילו כבר יש בו בקשה.
פתרון התרגיל השני¶
לפני הסגירה המונה הוא שתיים. הסגירה משנה מצב לclosing ומונעת הגשות חדשות, אבל אינה מורידה את המונה. השלמת הכתיבה מורידה לאחת ומשחררת את בעלות הפעולה על הbuffer שלה. השלמת הקריאה מורידה לאפס, ואז אפשר לשחרר את החיבור אם אין עוד בעלים אחרים כמו רשומת timer או callback של יישום.
אם הקריאה הצליחה לפני הביטול, עדיין נקבל ונעבד את completion שלה פעם אחת. מצב closing יכול לגרום לנו לוותר על יצירת בקשה עסקית מהמידע, אבל לא לדלג על שחרור הבעלות. בקשת ביטול וcompletion הם אירועים שונים; חיבור שמוריד מונה על שניהם עלול להשתחרר פעמיים.
נחזיק reference גם בכל callback של timer שמצביע לחיבור, ונבטל או ננקז אותו לפי חוזהו. ספירה של פעולות socket בלבד אינה מספיקה אם נתנו את אותו pointer לרכיב אחר.
פתרון התרגיל השלישי¶
הגבול המקומי המצטבר של מאה חיבורים יכול להגיע ליותר משני מגהבייט, ולכן המגבלה הגלובלית צריכה להיבדק בנפרד. לפני הקצאת תשובה נשמור תקציב מקומי וגלובלי באופן שלא מאפשר לשתי פעולות לעבור יחד את הגבול. אם שמירת אחד מהם נכשלת, נחזיר את השני.
נשתמש באובייקט בעלות על התקציב. הוא עובר עם התשובה לתור, נשאר עם הכתיבה הפעילה ומוחזר רק כשאין עוד צורך בbuffer. השלמה חלקית אינה משחררת בהכרח את כל התקציב, משום שהbuffer המקורי עדיין מחזיק את שאר התשובה.
כאשר אין מקום, נעצור הגשת קריאות נוספות לחיבור בהתאם לframing ולמדיניות, או נחזיר שגיאת עומס לפני ביצוע עבודה חדשה. לא נכניס את הבקשה לתור "זמני" בלתי מוגבל. נמדוד בנפרד זיכרון connection, parser, בקשות, תשובות ופעולות פעילות, כדי שהbound לא יכסה רק את התור הנוח למדידה.
בבדיקת הלקוח האיטי נריץ במקביל לקוח תקין ונמדוד את ההתקדמות שלו. נבדוק שהתור המוגבל אינו מוחזק תחת נעילה בזמן send או המתנה, ושמדיניות התזמון נותנת זמן עבודה גם לחיבורים אחרים. הגבלת זיכרון לבדה אינה הוכחה להוגנות.