وقتی یک عامل به‌تنهایی کار می‌کند، تمامی فرآیندها در مسیری واحد طی می‌شوند و خطای هماهنگی معنایی ندارد. اما به‌محض ورود چندین عامل، چالش‌های جدیدی رخ می‌نمایند: پیام‌ها از دست می‌روند، دو عامل به‌طور هم‌زمان بر روی موضوعی واحد کار می‌کنند، یا زنجیره در میانه‌ی کار از هم می‌پاشد. معماری رویدادمحور پاسخی به این خطرهاست؛ در ادامه نحوه کارکرد آن را بررسی می‌کنیم.

رویداد به‌جای فراخوانی مستقیم

در یک معماری رویدادمحور، عامل‌ها یکدیگر را به‌طور مستقیم فراخوانی نمی‌کنند. در عوض، هر عامل پس از اتمام کار خود، یک رویداد منتشر می‌کند — مانند «عملیاتِ فلان انجام شد» — و سایر اجزایی که به آن رویداد گوش می‌سپارند، واکنش نشان می‌دهند. این مستقل‌سازی بدین معناست که هیچ عاملی نیاز ندارد بداند گام بعدی چیست؛ بلکه صرفاً اعلام می‌کند کارش پایان یافته است.

رویداد محرک است، حافظه مرجع حقیقت

یک قاعده کلیدی، تمایز میان محرک و مرجع حقیقت است. رویداد صرفاً یک اعلان است و نباید داده‌های حجیم را با خود حمل کند. رویداد تنها شامل یک شناسه است — برای مثال: «شناسه این کار فلان است» — و هر جزئی که واکنش نشان می‌دهد، وضعیت به‌روز را از حافظه مشترک می‌خواند، نه از خود رویداد. چرا؟ زیرا اگر داده را درون رویداد قرار دهید، ممکن است تا زمان رسیدن منقضی شده باشد. حافظه تنها مرجع حقیقت است؛ رویداد فقط می‌گوید: «تغییری رخ داده، بررسی کنید».

تحویل دست‌کم یک‌بار

برای جلوگیری از گم شدن پیام‌ها، رویدادها باید ماندگار باشند. الگوی رایج، تحویلِ دست‌کم یک‌بار است: رویداد در یک صف ماندگار ذخیره می‌شود و مصرف‌کننده تنها پس از پردازش موفق، آن را تأیید می‌کند. اگر پردازش با شکست مواجه شود و تأییدیه‌ای نرسد، رویداد دوباره تحویل داده می‌شود. این یعنی هیچ پیامی بدون پیگیری رها نمی‌شود. همچنین رویدادهایی که حتی پس از چند بار تلاش پردازش نمی‌شوند، به یک صف نامه‌های مرده منتقل می‌شوند تا مورد بررسی قرار گیرند — نه اینکه در سکوت ناپدید شوند.

ناظر تکمیل: تصمیم‌گیرنده قطعی

در هسته این معماری، نقشی ویژه قرار دارد: ناظر تکمیل. این جزء به تمامی رویدادهای «پایان کار» گوش می‌دهد، وضعیت کارها را از حافظه مشترک می‌خواند (نه از رویداد) و تصمیم می‌گیرد گام بعدی چیست: آیا باید کار دیگری آغاز شود یا زمان تولید پاسخ نهایی فرا رسیده است. نکته مهم این است که این تصمیم‌گیری کاملاً قطعی است — یک مدل زبانی در آن دخالت ندارد. چون تصمیم بر اساس وضعیت جدید و قوانین روشن اتخاذ می‌شود، احتمال بروز تداخل هم‌زمانی و گم شدن پیام‌ها از بین می‌رود.

مقایسه با دیگر شیوه‌های ترکیب

هماهنگ‌سازی رویدادمحور تنها راه همکاریِ چند عامل در کنار یکدیگر نیست؛ این روش یکی از معدود الگوهای موجود است و درک جایگاه آن به ما در انتخاب مسیر مناسب کمک می‌کند. در الگوی «هماهنگ‌کننده»، عاملی مرکزی تصمیم می‌گیرد که کدام عامل و با چه ترتیبی اجرا شود؛ اگرچه دنبال کردن این ساختار آسان است، اما خودِ هماهنگ‌کننده به نقطه‌ای واحد برای شکست تبدیل می‌شود که همهٔ بخش‌ها را معطلِ خود می‌کند. در الگوی «خط لوله»، جریان کار در مسیری ثابت میان عامل‌ها پیش می‌رود و هر مرحله، خروجیِ گام قبلی را تغییر می‌دهد؛ رویکردی پیش‌بینی‌پذیر اما انعطاف‌ناپذیر، زیرا هر گام به ساختار گامِ پیشین وابسته است. در الگوی «مش (mesh)»، عامل‌ها همتایانی هستند که آزادانه یکدیگر را فرا می‌خوانند؛ ساختاری منعطف، اما با هماهنگیِ ضمنی که در صورت بروز خطا، ردیابی و عیب‌یابی آن بسیار دشوار خواهد بود.

رویکرد رویدادمحور، انعطاف‌پذیریِ الگوی مش را حفظ می‌کند — چرا که هیچ عاملی مستقیماً به عامل بعدی متصل (سیم‌کشی) نشده است — و در عین حال، بر نقطهٔ ضعف اصلی آن غلبه می‌کند؛ زیرا ردپای «رویدادهای رخ‌داده و گام بعدی» در دو جایگاه مشخص و قابل‌بررسی ثبت و نگهداری می‌شود: صف ماندگار رویدادها و ناظر تکمیلِ قطعی. با این کار، اگرچه سادگی و وضوحِ در یک نگاهِ خط لولهٔ ثابت را از دست می‌دهید، اما در مقابل به سامانه‌ای دست می‌یابید که در شرایط بار سنگین و توسعهٔ مقیاس، بدون از دست رفتن پیام‌ها، تاب می‌آورد و انعطاف نشان می‌دهد. مانند بیشتر تصمیم‌های معماری، الگو باید از صورت‌مسئله پیروی کند: هرگاه اجزای سامانه پرشمار، مستقل و مستعد تغییر مداوم باشند، باید به‌سراغ رویکرد رویدادمحور رفت؛ اما برای یک جریان کاری مستقیم و تک‌مسیره، همان خط لولهٔ ساده همچنان راهکار ساده‌تر و مناسب‌تری است.

چرا این طراحی فرونمی‌پاشد

ارزش این معماری در تفکیک شفاف مسئولیت‌هاست. رویدادها اعلان‌هایی ساده هستند (تنها شناسه، بدون داده). حافظه تنها مرجع حقیقت است (بدون کپی‌های موازی در بخش‌های مختلف سامانه). نقش‌های تصمیم‌گیرنده قطعی هستند (نه احتمالی). و چون هر جزء وظیفه‌ای محدود و مشخص دارد، شکست یک بخش به سایر بخش‌ها سرایت نمی‌کند. این همان چیزی است که یک تیم چندعاملی را از زنجیره‌ای شکننده به سامانه‌ای پایدار تبدیل می‌کند — سامانه‌ای که حتی زیر بار کاری شدید نیز پیامی گم نمی‌کند.