چگونه امروز این مشکل را حل میکنم ⚡️🖥
امروز، همچنان با همان دکمه UI شروع میکنم. کاربر روی «Generate Report» کلیک میکند، اما به جای انتظار، backend درخواست را میپذیرد، آن را جایی ذخیره میکند (مثلاً به عنوان یک رکورد job در دیتابیس) و بلافاصله پاسخ میدهد. این جوهرهی ساخت asynchronous APIs است. سپس job توسط یک background worker پردازش میشود.
این worker میتواند یک hosted service، یک Quartz job، یا حتی یک AWS Lambda Function فعالشده توسط پیام صف (queue message) باشد. این وظیفه را انجام میدهد: دادهها را جمعآوری میکند، فایل را میسازد و آن را در فضایی مثل S3 یا Azure Blob آپلود میکند. 📂☁️
زمانی که گزارش آماده شد، worker وضعیت job را به «completed» بهروزرسانی میکند و به کاربر اطلاع میدهد. این میتواند یک ایمیل با لینک دانلود یا پیام real-time SignalR باشد که در برنامه نمایش داده میشود. لینک به فایل ذخیرهشده اشاره دارد و از طریق backend به صورت امن ارائه میشود.
مزیت این روش 🌟
اکنون کاربر منتظر یک HTTP request طولانی نیست. سرور connections را برای دقیقهها باز نگه نمیدارد. اگر چیزی خراب شد، میتوان آن را به صورت خودکار retry کرد. همچنین امکان ردیابی پیشرفت یا لغو job وجود دارد. اگر صد کاربر به طور همزمان درخواست گزارش بدهند، سیستم بدون قفل شدن scale میشود.
تجربه برای کاربر سریعتر به نظر میرسد، حتی اگر زمان واقعی تولید گزارش تغییر نکرده باشد. زیرا در نهایت، کاربران به performance metrics اهمیت نمیدهند، بلکه responsiveness برایشان مهم است. ⚡️
چرا هنوز از این سوال استفاده میکنم 🧐
چند سال بعد، شروع به استفاده از همین سوال در مصاحبه با توسعهدهندگان دیگر کردم. نه برای فریب کسی، بلکه چون نشان میدهد افراد چگونه فکر میکنند.
برخی کاندیداها مستقیم به بهینهسازی کد و queries میروند، دقیقاً مثل من در گذشته. این نشان میدهد که آنها با performance tuning آشنا هستند. سپس میتوانم به سوالات فنی پیشرفته درباره algorithms، data structures یا database optimization بپردازم.
برخی لحظهای مکث میکنند و درباره تجربه کاربر، پردازش background و fault tolerance فکر میکنند. اینجاست که گفتگوی واقعی شروع میشود: queues، retries، اطلاعرسانی، اشتراک امن فایل و غیره. این سناریو میتواند به بحثهای گستردهتری درباره system design منجر شود.
هیچ پاسخ واحدی درست نیست. اما تفاوت بزرگی بین کسی که فقط روی کد تمرکز میکند و کسی که میتواند یک سیستم scalable طراحی کند وجود دارد.
درس مهم 🎓
وقتی اولین بار این سوال را شنیدم، به فکر سریعتر کردن کد بودم. اکنون به فکر بهتر کردن تجربه کاربر هستم.
بهینهسازی یک query یا حلقه میتواند کمک کند، اما مشکل انتظار، خطاها یا مقیاسپذیری را حل نمیکند. اگر کاربران زیادی همزمان همان گزارش را شروع کنند، طراحی synchronous به سرعت شکست میخورد. جریان asynchronous سیستم را پاسخگو و مقاوم نگه میدارد، بدون توجه به بار کاری.
این تغییر از بهینهسازی توابع به طراحی سیستمهای scalable تفاوت بین یک توسعهدهنده خوب و یک توسعهدهنده عالی است. 🏆
امیدوارم مفید بوده باشد.🤍