ساخت یک خط لوله تحویل ایمن برای عاملها
اکثر دموهای عاملها یک سوال حیاتی را نادیده میگیرند. چگونه به یک سیستم خودگردان اجازه میدهید بدون ارسال تکراری یا ارسال کارهای تایید نشده، از طرف شما چیزی را ارسال کند؟
ارسال تکراری یک خطای نادر نیست. این رفتار پیشفرض یک صف ساده است، زمانی که یک کارگر (worker) در میانه انجام وظیفه از کار میافتد. یک کارگر پیامی را ارسال میکند و سپس قبل از ثبت موفقیت، کرش میکند. سیستم تصور میکند وظیفه با شکست مواجه شده و به کارگر جدید میگوید دوباره تلاش کند. مشتری دو ایمیل دریافت میکند و شما یک تیکت پشتیبانی.
شما نمیتوانید از هر کرشی جلوگیری کنید. باید برای کرش کردن در فاصله زمانی بین «انجام عمل» و «ثبت آن» طراحی کنید.
برای هر خروجی عاملی که پیامدهای واقعی دارد، از این خط لوله شش مرحلهای استفاده کنید:
• تولید (Produce): عامل، محصول (artifact) کامل را تولید میکند. هنوز چیزی ارسال نمیکند. • ذخیرهسازی (Persist): ابتدا قصد (intent) و محصول را در یک ذخیرهساز بادوام (durable storage) بنویسید. • امتیازدهی (Score): یک امتیاز اطمینان به خروجی اختصاص دهید. • بازبینی (Review): موارد با اطمینان پایین را به یک انسان ارجاع دهید. • تایید (Approve): از یک دروازه «شکست-بسته» (fail-closed) استفاده کنید. سیستم تمام ارسالها را مسدود میکند مگر اینکه یک انسان مجوز صریح صادر کند. • ارسال و گواهی (Send and Attest): مورد را تحت یک اجاره (lease) ارسال کنید، سپس یک رسید اثبات بنویسید.
هر مرحله باید یک انتقال بادوام و مجزا باشد. وضعیت (state) در پایگاه داده شما ذخیره میشود، نه در حافظه یک کارگر.
برای جلوگیری از موارد تکراری، از اجاره در سطح ردیف (row-level leasing) استفاده کنید. در Postgres، از SELECT ... FOR UPDATE SKIP LOCKED استفاده کنید. این کار تضمین میکند که در هر لحظه فقط یک کارگر مالک یک وظیفه باشد.
مهمترین قانون، نحوه مدیریت اجارههای منقضی شده است. اگر یک کارگر هنگام ارسال یک پیام خارجی از کار افتاد، آن را به طور خودکار دوباره امتحان نکنید. در عوض، وظیفه را برای بازبینی انسانی معلق بگذارید. یک وظیفه متوقف شدهی قابل مشاهده، بهتر از یک ارسال تکراری نامرئی است.
همچنین باید از اصول «شکست-بسته» (fail-closed) پیروی کنید:
- ارسال به طور پیشفرض خاموش است. یک پرچم (flag) واحد باید تمام ترافیک خروجی را فعال کند.
- هویت بررسی میشود. سیستم باید آدرس فرستنده و امنیت انتقال را در لحظه ارسال تأیید کند.
- هر چیزی یک رسید به جا میگذارد. یک ارسال ثبتنشده، یک شکست است.
این را برای کارهای کماهمیت مانند لاگهای داخلی نسازید. زمانی از آن استفاده کنید که یک اشتباه باعث هزینه مالی شود، مشکل حقوقی ایجاد کند یا نیاز به تیکت پشتیبانی داشته باشد.
Optional learning community: https://t.me/GyaanSetuAi
