در زبان برنامهنویسی Rust، برنامهنویسی ناهمگام (asynchronous programming) برای نمایش عملیاتهای بالقوه طولانیمدتی که ممکن است بلافاصله تکمیل نشوند، به مفهوم «آیندهها» (futures) متکی است. این «آیندهها» (futures) به مکانیزمی برای هدایت اجرا و تکمیل خود نیاز دارند. اینجاست که «اجراکنندههای ناهمگام» (async executors) وارد عمل میشوند.
یک مجری ناهمگام (async executor) مسئول مدیریت و اجرای این Futures (آیندهها) است. این محیط را فراهم میکند که در آن میتوان Futures را برنامهریزی کرد، از پیشرفت آنها نظرسنجی کرد و در نهایت آنها را به سمت تکمیل هدایت کرد. آن را به عنوان یک هماهنگکننده (orchesterrator) در نظر بگیرید که پیچیدگیهای وظایف ناهمگام را مدیریت میکند و به کد شما اجازه میدهد تا پاسخگو و کارآمد باقی بماند.
Rust اجراکنندههای ناهمگام مختلفی ارائه میدهد که هر کدام نقاط قوت و ویژگیهای خاص خود را دارند.
اجراکنندههای ناهمزمان
انتخاب اجراکننده برای سرویس Rust شما به شدت به ماهیت حجم کاری آن بستگی دارد. اگرچه Tokio یک محیط اجرای ناهمزمان قدرتمند است، اما ممکن است برای همه سناریوها راهحل بهینه نباشد.
برای سرویسهایی که عمدتاً عملیات متوالی را اجرا میکنند، معرفی یک زمان اجرای ناهمزمان مانند Tokio ممکن است سربار غیرضروری ایجاد کند بدون اینکه افزایش عملکرد قابل توجهی داشته باشد. در چنین مواردی، یک مجری تکرشتهای ممکن است انتخاب مناسبتر و سبکتری باشد. این رویکرد، پایگاه کد را ساده کرده و مصرف منابع را کاهش میدهد.
پیکربندی نخهای کارگر
هنگام کار با سرویسهایی که ذاتاً عملیات همزمان یا ناهمزمان دارند، استفاده از قابلیتهای یک زمان اجرای ناهمزمان مانند Tokio بسیار مهم میشود. برای به حداکثر رساندن عملکرد در این سناریوها، زمان اجرا را طوری پیکربندی کنید که از تعدادی نخ کارگر استفاده کند که با تعداد هستههای CPU موجود در سیستم مطابقت داشته باشد. این به زمان اجرا اجازه میدهد تا بار کاری را به طور مؤثر توزیع کند و از قدرت پردازش موجود نهایت استفاده را ببرد.
هنگام پیکربندی threadهای کارگر، محیط کلی سیستم را در نظر بگیرید. اگر چندین سرویس به طور فعال روی یک ماشین مجازی در حال اجرا هستند، تعداد threadهای کارگر را برای هر سرویس تنظیم کنید تا از استفاده بیش از حد CPU جلوگیری شود و تخصیص منابع عادلانه بین همه فرآیندهای فعال تضمین شود.
عملیات مسدود کردن
بسیار مهم است که اطمینان حاصل شود که نخهای کارگر در یک زمان اجرای ناهمزمان هرگز توسط عملیات طولانی مدت یا همزمان مسدود نمیشوند. مسدود کردن یک نخ کارگر میتواند به شدت مانع توانایی زمان اجرا در پردازش وظایف ورودی و حفظ پاسخگویی شود.
اگر تابعی که روی یک نخ کارگر اجرا میشود نیاز به انجام عملیات مسدود کردن داشته باشد، از tokio::spawn_blocking استفاده کنید. این تابع عملیات مسدود کردن را به یک مخزن نخ جداگانه که مخصوص چنین وظایفی طراحی شده است، منتقل میکند و از هرگونه اختلال در نخهای کارگر ناهمزمان جلوگیری کرده و پاسخگویی کلی سرویس را تضمین میکند.