گذرگاه رویداد
وقتی اتفاقی میافتد که ارزش دانستن دارد، پنل یک رویداد ایجاد میکند و آن را به هر مشترکی که خواسته تحویل میدهد: وبهوکها، افزونهها، چتهای تلگرام و آدرسهای ایمیل. این صفحه توضیح میدهد یک تحویل چطور انجام میشود و گیرنده روی چه چیزی میتواند حساب کند. فهرست رویدادها و محتوایشان در فهرست رویدادها آمده است؛ راهاندازی وبهوک در وبهوکها و رویدادها.
روی هر جعبه بزنید تا ببینید آنجا چه اتفاقی میافتد.
رویدادها تغییرها را گزارش میدهند
هر رویداد میگوید چیزی تغییر کرده است: حسابی به سهمیهاش رسید، نودی دیگر جواب نداد، ادمینی از آدرس تازهای وارد شد، پشتیبانگیریای تمام شد. وضعیتی که ادامه دارد یک بار گزارش میشود، وقتی شروع میشود، و جایی که معنا دارد یک بار دیگر وقتی تمام میشود (پر شدن دیسک یک نود، و بعد برگشتنش). نودی که فقط خاموش است با هر ضربان رویداد ایجاد نمیکند.
هشدارهایی که باید از ریاستارت جان سالم به در ببرند، مثل هشدار انقضای یک حساب یا سلامت یک افزونه، در پایگاه داده به خاطر سپرده میشوند، پس ریاستارت پنل هیچکدامشان را تکرار نمیکند. چند وضعیت که با زمانسنج سنجیده میشوند، مثل نمایندهای که از سهمیهاش گذشته، در حافظه به خاطر سپرده میشوند، و ریاستارت ممکن است هر کدام را یک بار تکرار کند.
چهار خانواده
اولین کلمهی نام رویداد میگوید دربارهی چیست، و همین تعیین میکند چه کسی میتواند آن را بشنود:
| خانواده | دربارهی | نمونهها |
|---|---|---|
user.* | یک حساب؛ همیشه ادمینی را که مالک آن است نام میبرد | user.quota_reached، user.expiring، user.first_fetch |
node.* | یک نود | node.disconnected، node.disk_high، node.rejections_high |
admin.* | حساب یک اپراتور | admin.login_new_ip، admin.resale_cap_reached |
panel.* | خود نصب؛ هرگز حسابی را نام نمیبرد | panel.backup_failed، panel.cert_expiring، panel.addon_unhealthy |
چون هر رویداد user.* مالکش را نام میبرد، یک اعلان میتواند به نمایندهای برسد که آن مشتری مال اوست. رویداد panel.* هیچوقت به مشترکی که به یک نماینده وابسته است نمیرسد.
صندوق خروجی
ایجاد یک رویداد یک تراکنش پایگاه داده است:
- رویداد یک بار در صندوق خروجی نوشته میشود.
- برای هر مشترک فعالی که فیلتر رویدادش آن را میخواهد، و مالکش اجازهی دیدنش را دارد، یک ردیف تحویل کنارش نوشته میشود.
وقتی هیچ مشترکی رویدادی را نخواهد، اصلاً چیزی نوشته نمیشود، پس نصبی که مشترک ندارد جدولی خالی نگه میدارد. چون رویداد و تحویلهایش با هم نوشته میشوند، رویداد هیچوقت نیمهکاره تحویل نمیشود: یا تحویل همهی مشترکها منتظر است، یا هیچکدام.
رویدادها و تحویلها به مدت نگهداری رویدادها نگه داشته میشوند، بهطور پیشفرض ۷ روز و حداکثر ۹۰ روز، و بخشی از هر پشتیبان هستند.
تحویل و تلاش دوباره
یک کارگر پسزمینه در پنل تحویلهایی را که وقتشان رسیده میفرستد:
- به ترتیب برای هر مشترک. تحویلهای هر مشترک یکی پس از دیگری میروند، پس گیرنده رویدادها را به ترتیبی که اتفاق افتادهاند میبیند. مشترکهای مختلف منتظر هم نمیمانند.
- شکست دوباره تلاش میشود، بعد از تأخیری که هر بار دو برابر میشود، از ۳۰ ثانیه شروع و حداکثر یک ساعت، با کمی تصادف تا تلاشهای دوباره همزمان نرسند.
- بعد از ۱۰ تلاش، تحویل مرده است. با آخرین پاسخش در فهرست میماند، و ارسال دوباره آن را دستی دوباره امتحان میکند.
- یک مشترک فقط وقتی خاموش میشود که شکستهایش هم یک رشتهی طولانی باشند و هم بیش از یک روز عمر داشته باشند. گیرندهای که یک ساعت از کار افتاده بود و صفی از تلاشهای دوباره رویش انباشته شده، خاموش نمیشود. روشن کردن دوبارهاش شمارش را از نو شروع میکند.
- redirectها دنبال نمیشوند.
ارسال رویداد آزمایشی فوراً panel.ping را میفرستد و پاسخ گیرنده را نشان میدهد.
پاکت
وبهوک یک POST با بدنهی JSON دریافت میکند:
{
"v": 1,
"id": 1842,
"event": "user.quota_reached",
"time": 1791711000,
"data": { "userId": 57, "name": "ali", "adminId": 3 },
"recipients": [3]
}id شناسهی خود رویداد است، برای هر مشترک و هر تلاش دوباره یکسان. time به ثانیهی Unix است. recipients، وقتی باشد، ادمینهایی را فهرست میکند که رویداد دربارهی آنهاست.
همراهش سه هدر میآید:
| هدر | چه چیزی حمل میکند |
|---|---|
X-Nexora-Event | نام رویداد |
X-Nexora-Delivery | شناسهی تحویل؛ تلاش دوباره همان را تکرار میکند، پس گیرنده تکراریها را با این شناسه کنار میگذارد |
X-Nexora-Signature | یک مهر زمانی و یک HMAC-SHA256 از مهر زمانی و بدنه، ساختهشده با secret مشترک |
گیرنده امضا را با secretی بررسی میکند که یک بار، هنگام ساختن مشترک، به او نشان داده شده است. بازگردانی از پشتیبان جدول تحویلها را هم برمیگرداند، پس بعد از آن شناسههای تحویل ممکن است تکرار شوند: گیرندهای که شناسهها را در طول یک بازگردانی نگه میدارد باید با panel.restore_applied از نو شروع کند.
محتوای کمحجم
محتوای رویداد شناسهها، نامها و آنچه تغییر کرده را حمل میکند، هرگز اطلاعات ورود را: نه گذرواژه، نه کلید، نه توکن اشتراک و نه لینک. گیرندهای که بیشتر لازم دارد آن را با توکن خودش و زیر مجوزهای خودش از API میخواند.
- عملهای گروهی و ساخت دستهای یک رویداد خلاصه ایجاد میکنند، نه یکی برای هر حساب.
panel.settings_changedنام تنظیم را میبرد، هرگز مقدارش را.
چه کسی کجا میتواند مشترک شود
- وبهوکی که دستی اضافه میکنید نمیتواند به شبکهی خود پنل اشاره کند: آدرسهای loopback، خصوصی و مشابه هنگام اتصال پنل رد میشوند، نام به هر چه resolve شود.
- وبهوک یک افزونه متعلق به توکن API آن است. فقط رویدادهایی را میشنود که از manifest آن تأیید کردهاید، میتواند به افزونهای که کنار پنل روی یک شبکهی خصوصی اجرا میشود برسد، و تا وقتی افزونه تعلیق است ساکت است.
کانالهایی که به آدمها میرسند
چتهای تلگرام و آدرسهای ایمیل آدماند، نه برنامه. گذرگاه هر تحویل را بهجای یک POST به فرستندهی تلگرام یا ایمیل میدهد، با همان تلاشهای دوباره، و اول فیلترش میکند:
- یک چت یا آدرس فقط چیزی را میشنود که نقش حسابش اجازهی خواندنش را دارد. چت یک نماینده دربارهی مشتریهای خودش میشنود و نه چیز دیگری.
- سرویس خاموش هیچ چیزی تحویل نمیدهد.
- آدرس ایمیل باید تأیید شود پیش از اینکه چیزی برایش فرستاده شود.
گذرگاه بهعنوان نشانهی سلامت
تحویلی که هرگز نرسد چیزی به گیرندهاش نمیگوید. برای همین پنل تعداد تحویلهای در انتظار، تحویلشده و مرده را همیشه روی endpoint معیارهایش منتشر میکند، تا هشداری روی تحویلهای مرده بتواند فعال شود؛ ببینید پایش و معیارها.
