دسکتاپ، Worker و محاسبات محلی · فصل ۲ — Supervisor، Executor و Coordinator · 181
Local Coordinator Skeleton و Protocol Role
اپ یا worker محلی را اجرا میکند اما device identity، privilege، offline state و fleet behavior را طراحی نکرده است. موضوع جاری: «Local Coordinator Skeleton و Protocol Role». میتواند «Local Coordinator Skeleton و Protocol Role» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
خلاصهٔ درس
اپ یا worker محلی را اجرا میکند اما device identity، privilege، offline state و fleet behavior را طراحی نکرده است. موضوع جاری: «Local Coordinator Skeleton و Protocol Role».
میتواند «Local Coordinator Skeleton و Protocol Role» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
خروجی این درس
میتواند «Local Coordinator Skeleton و Protocol Role» را برای یک node محلی با identity، state، privilege و recovery boundary مناسب طراحی کند.
1. مسئله واقعی: socket موفق مساوی protocol درست نیست
وقتی supervisor و executor با objectهای مشترک، JSON آزاد یا پیام fire-and-forget به هم وصل شوند، قطع اتصال یا retry ساده میتواند یک عملیات state-changing را دوبار اجرا کند. خروجی این درس Local Coordinator Protocol Envelope & Role Contract v1 است: قراردادی transport-neutral که roleها، version، request identity، deadline، capability، typed result/error و retry semantics را صریح میکند تا بدانیم چه چیزی درخواست شد، چه چیزی پذیرفته شد و چه چیزی واقعاً نتیجه داد.
2. مرز مالکیت LOC-008
این درس نقش coordinator/supervisor/executor و envelope پروتکل بین آنها را مالک است. Enrollment و short-lived identity در LOC-009 است؛ health telemetry در LOC-010؛ executor sandbox internals در LOC-007. یک transport محلی موفق فقط delivery path را نشان میدهد و بهتنهایی نه authorization، نه execution success و نه worker health را ثابت میکند.
3. Roleها را قبل از message schema جدا کنید
Supervisor مسئول orchestration و درخواست است؛ coordinator مسئول validation، correlation، bounded routing و protocol state است؛ executor مسئول اجرای عملیات در boundary خودش است. اگر coordinator مستقیماً implementation detailهای executor را import کند، protocol contract عملاً از process boundary عبور کرده و versioning و recovery قابل ممیزی از بین میرود.
4. JSON-RPC چه pattern مفیدی میدهد
JSON-RPC 2.0 در Request از id برای correlation با Response استفاده میکند. Notification id ندارد و server برای آن response برنمیگرداند. این فقط یک reference pattern است: MAKNOW مجبور به JSON-RPC نیست، اما lesson از همین تفاوت برای جداکردن «request قابل تأیید» از «notification بدون confirmation» استفاده میکند.
5. هر envelope باید version و identity صریح داشته باشد
حداقل protocol_version، message_type، operation، request_id، correlation_id، sender/receiver role و payload schema را ثبت کنید. Version نباید از transport path یا method name حدس زده شود. Request identity باید بین retryها پایدار بماند تا supervisor بتواند response، duplicate و timeout را به همان intent اولیه وصل کند.
6. State-changing retry بدون idempotency خطرناک است
برای operationهای retryable که state را تغییر میدهند، idempotency_key و duplicate rule لازم است. اگر connection بعد از acceptance قطع شود و supervisor با identity جدید retry کند، executor ممکن است همان job را دوباره شروع کند. Retry با همان idempotency identity باید بتواند نتیجه قبلی را replay، request را duplicate علامتگذاری یا status آن را query کند؛ نه اینکه بیخبر re-execute کند.
7. Notification را فقط برای effect بدون confirmation بهکار ببرید
Notification چون response ندارد، برای کاری که success/failure آن باید audit شود انتخاب مناسبی نیست. اگر start_job به نتیجه قطعی نیاز دارد، notification semantics کافی نیست. Fire-and-forget را به signalهایی محدود کنید که عدم دریافت confirmation برایشان از نظر contract قابل قبول است و failure آنها authority یا state بحرانی را مبهم نمیکند.
8. Deadline و timeout باید داخل contract باشند
deadline را در envelope نگه دارید و timeout را state واقعی بدانید. اگر deadline گذشته است، late response نباید silently به success تبدیل شود. سیستم باید روشن کند آیا operation ممکن است server-side ادامه یافته باشد، آیا status query لازم است و آیا retry مجاز است. Timeout یعنی «نتیجه در window مورد انتظار ثابت نشد»، نه «حتماً اجرا نشده».
9. Role/Capability check قبل از dispatch انجام شود
Coordinator باید operation را با sender role، receiver role و role_capability مقایسه کند. Method name معتبر ولی capability نامعتبر باید DENIED شود. این درس authorization system کامل نمیسازد؛ فقط تضمین میکند protocol skeleton اجازه نمیدهد operation خارج از capability صرفاً چون transport local است dispatch شود.
10. Typed error بهتر از exception مبهم است
Response باید success result یا typed error داشته باشد و correlation identity را حفظ کند. error_code و error_detail باید به اندازه لازم برای recovery و audit کافی باشند. خطاهای DENIED، TIMEOUT، DUPLICATE و INCOMPATIBLE نباید در یک generic failure گم شوند، چون هر کدام retry/recovery متفاوتی دارند.
11. Protocol Buffers چه lesson سازگاری میدهد
در Protocol Buffers، field number هویت field روی wire است و نباید reuse شود. وقتی field حذف میشود، reserve کردن number جلوی استفاده ناسازگار بعدی را میگیرد. MAKNOW مجبور به protobuf نیست، اما از این constraint بهعنوان pattern استفاده میکند: optional field جدید باید old peer را نشکند و field بازنشسته نباید با معنای تازه دوباره زنده شود.
12. Unknown field و retired field را policyدار کنید
برای version evolution، unknown_field_rule و reserved_field باید معلوم باشند. Peer قدیمی میتواند optional field جدید را نادیده بگیرد فقط اگر semantic core request حفظ شده باشد. اگر field حذفشده برای correctness ضروری بوده، صرف ignore کردن کافی نیست و نتیجه باید INCOMPATIBLE یا migration-required باشد.
13. Transport binding نباید protocol semantics را تعیین کند
Unix-domain socket، Windows named pipe یا transport محلی دیگری فقط carrier است. request_id، version، deadline، role checks، idempotency و typed result/error باید با تغییر transport ثابت بمانند. Transport-specific auth یا ACL میتواند evidence اضافه کند، اما protocol contract نباید با path یا API همان transport یکی شود.
14. Failure Probeهای تعیینکننده
چهار shortcut را بشکنید: (1) state-changing notification بدون response requirement؛ (2) retry با request جدید بعد از acceptance نامشخص؛ (3) sender role بدون capability؛ (4) peer قدیمی با schema ناسازگار یا reuse field بازنشسته. علاوه بر آن deadline expiry و duplicate replay را تست کنید. Lab answer label را از learner پنهان نگه میدارد و فقط evidence را میدهد.
15. Transfer: Unix socket → Windows local transport + schema evolution
در Transfer، Unix-domain socket را با Windows local transport جایگزین کنید، سپس یک response field اختیاری جدید اضافه و یک field قدیمی را retire کنید. ثابتها protocol versioning، request identity، role/capability، deadline، typed errors، duplicate rule و audit semantics هستند. Transport و schema change باعث میشوند compatibility از evidence جدید دوباره محاسبه شود؛ baseline verdict قابل کپی نیست.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
Q1 application
Construct a versioned coordinator request/response envelope for a retryable local start_job operation.
Q2 diagnosis
Explain why a dropped connection after acceptance cannot be repaired by sending the same state-changing intent with a fresh request identity.
Q3 decision
Issue a typed result when the sender lacks the operation capability or the request deadline has expired.
Q4 transfer
Move the same contract from a Unix-domain socket to a Windows local transport while adding an optional response field and reserving a retired field.
ملاکهای ارزیابی (rubric)
- Role boundary — critical: supervisor, coordinator, and executor responsibilities remain distinct.
- Correlation — critical: request/response identity is explicit and retry-safe.
- Idempotency — critical: retryable state changes cannot be blindly executed twice.
- Capability/deadline — critical: unauthorized or expired requests remain typed non-success states.
- Compatibility — critical: version evolution preserves optional-field and retired-field rules.
- Transfer — critical: transport changes without changing protocol semantics.
منابع و تازگی
مطالعهٔ موارد (case studies)
تصاویر درس
فایلهای آزمایشگاه
Implement evaluate_protocol(case) in starter.py. Keep protocol version, role/capability, correlation, idempotency/duplicate state, deadline, compatibility, decision, and reason separate.
The eight fixtures are synthetic and offline. They do not contain final decision labels. case_08 is the transfer: Windows local transport plus an added optional response field and a retired field that remains reserved. Run python run_checks.py to verify only learner-visible structure.