לדלג לתוכן

פרויקט שירות עבודות

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

הפרויקט משתמש במנוע הI/O ובjournal מפרקי המקביליות והקבצים. לא נוסיף מימוש קריפטוגרפי, parser של תמונות או גישה לנתיבי קובץ שהלקוח בוחר. בהמשך אפשר להחליף את פעולת החישוב, כל עוד שומרים על אותם גבולות וחיי משאבים.

חוזה המוצר

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

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

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

פרוטוקול

הגדירו header קבוע שכולל magic, גרסה, opcode, אורך body ומזהה בקשה. הגבילו את אורך ההודעה לפני הקצאה. בחרו סדר bytes מפורש וקידוד מוגדר למזהים; אל תשלחו struct של C++ כפי שהוא בזיכרון.

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

חיי עבודה

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

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

בעצירת שירות נסגרת הקבלה, הworkerים מגיעים לנקודות ביטול מוגדרות, וכל פעולת I/O מטופלת עד שאפשר לשחרר את משאביה. השירות מדווח stopped רק לאחר ניקוי. במקרה של סיום כפוי, העלייה הבאה משחזרת מתוך הjournal לפי חוזה ההתמדה שלו.

תצורה וסוד מדומה

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

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

מה בודקים

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

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

הגשה והגנה

הגישו קוד שירות ולקוח, הוראות בנייה והתקנה במכונה נקייה, תצורת הרשאות, בדיקות אוטומטיות ותחקיר של כשל אחד. ציינו את הbuild של ווינדוס, גרסאות הכלים וההנחות על filesystem והתמדה.

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