5 دقیقه مطالعه

سریال کلاس در Workflow، TypeScript پایدار را کمتر آزاردهنده می‌کند

Mehdi Rezaei
Mehdi
نویسنده

سریال کلاس در Workflow، TypeScript پایدار را کمتر آزاردهنده می‌کند

یکی از آزاردهنده‌ترین بخش‌های سیستم گردش کار پایدار این است که API خوب TypeScript را بدتر می‌کند. با یک شیء تمیز شروع می‌کنی که چیزی واقعی در سیستم را نمایندگی می‌کند. اولین مرز تعلیق یا ازسرگیری مجبورت می‌کند آن را به داده تخت تبدیل کنی. بعد هر قدم کمی رویه‌ای‌تر، تکراری‌تر، و کم‌صداقت‌تر نسبت به کاری می‌شود که کد واقعاً می‌کند.

برای همین پشتیبانی سریال سفارشی کلاس در Workflow SDK ارزش توجه دارد. ویژگی ویترینی نیست و انضباط سیستم پایدار را عوض نمی‌کند. چیزی که عوض می‌کند شکل کد است. می‌توانی دور مجموعه کوچکی از شیءهای واقعی گردش کار API بهتری را حفظ کنی، به‌جای اینکه سر هر مرز آن‌ها را دستی دوباره بسازی.

راه‌حل قدیمی بو می‌داد

قبل از این، جواب امن ساده بود: بین قدم‌ها داده شبیه JSON رد کن و هر چیز جزئی‌تر را خودت بساز. کار می‌کرد و هزینه داشت. دستگیره سندباکس می‌شد یک شناسه به‌علاوه یک ماژول کمک به‌علاوه متاداده شل. وظیفه بازبینی می‌شد یک رکورد تخت و چند تابع کمکی در جای دیگر. زمان اجرا پایدار می‌ماند، ولی کد دیگر با مدل ذهنی نمی‌خواند.

تیم باتجربه معمولاً با این معامله کنار می‌آید چون پایداری از ظرافت مهم‌تر است. اصطکاک دقیقاً جایی است که کد گردش کار باید تمیز خوانده شود. می‌خواهی دستگیره کار را ببینی و `cancel` را صدا بزنی. می‌خواهی سندباکس را ببینی و `runCommand` را صدا بزنی. نمی‌خواهی هر قدم با پنج خط بازسازی شروع شود تا به یک انتزاع مفید برسی.

چه چیزی عوض شد

Vercel قلاب سریال کلاس را از مسیر `@workflow/serde` اضافه کرد. جزئی مهم این است که نمونه کلاس هنوز به‌صورت داده سریال تخت ذخیره می‌شود. زمان اجرا وضعیت زنده فرآیند را برایت نگه نمی‌دارد. به‌جای آن راه صریح داری که بگویی کلاس چطور سریال شود و وقتی گردش کار از سر گرفته شد چطور دوباره ساخته شود.

تغییر API کوچک است و فایده عملی دارد. گردش کار هنوز مرز پایدار را رعایت می‌کند، ولی کد دو طرف مرز می‌تواند دور چیزی که واقعاً مدل می‌کنی شکل بماند. اگر deserialize کاری بیش از بازسازی از شناسه و چند فیلد انجام می‌دهد، احتمالاً داری منطق محصول را قایم می‌کنی.

کجا فوراً کمک می‌کند

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

با نحوه ساخته شدن گردش کار محصول AI هم می‌خواند. بخش سخت معمولاً یک صدای مدل نیست. زنجیره دور آن است: ساختن زمینه اجرا، نوشتن فایل، صدای ابزار، نقطه بازرسی وضعیت، انتظار برای انسان، ازسرگیری، تکرار امن، و فقط بعد ثبت نتیجه. اگر هر مرز، کد را به شیء بی‌نام و تابع کمکی تنزل بدهد، نگهداری سخت‌تر از حد لازم می‌شود.

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

جایی که تیم زیاده‌روی می‌کند

واکنش غلط این است که هر کلاس در دید را سریال کنی. گردش کار پایدار هنوز داده را ذخیره می‌کند نه منبع زنده را. کلاینت دیتابیس، کلاینت HTTP با وضعیت اتصال داخلی، سوکت باز، کش، نمونه SDK با داخل پنهان، و هر چیز وابسته به حافظه فرآیند محلی هنوز نباید از مرز ازسرگیری رد شوند.

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

دام سوم، فراموش کردن این است که گردش کار اغلب از یک استقرار بیشتر عمر می‌کند. اگر امروز شکل شیء را سریال کنی و هفته بعد بعد از تغییر کد از سر گرفته شود، deserializer باید با این واقعیت کنار بیاید. تحمل نسخه از نحو کلاس مهم‌تر است. فیلد جدید را اختیاری بدان و فیلد حذف‌شده را نادیده بگیر، نه اینکه فرض کنی حافظه کلاس با حافظه اجرای معلق یکی است.

قاعده تولید

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

در عمل یعنی شکل سریال کوچک بماند، رفت و برگشت را صریح تست کن، و هر متدی را که به دنیای بیرون دست می‌زند مرز عملیاتی بدان. این ویژگی تجربه توسعه‌دهنده را بهتر می‌کند. نگرانی معمول گردش کار پایدار را برنمی‌دارد: تکرار، idempotency، تأخیر، و اثر جانبی.

خیلی از ابزارهای گردش کار با قدرت بیشتر، کد را ناجورتر می‌کنند. این یکی جهت عکس است. سیستم پایدار را برای کار کردن خوشایندتر می‌کند بدون اینکه درباره هزینه پایداری دروغ بگوید. این شکل درست بهبود است. تفکر جادویی را تشویق نمی‌کند. اصطکاک بیهوده‌ای را برمی‌دارد که تیم باتجربه همین که از دموی اسباب‌بازی رد شود به آن می‌خورد.

اگر از قبل با Vercel Workflow می‌سازی، انتخابی به کار ببر. برای معدود شیءهایی که گردش کار را شبیه سیستمی که واقعاً ساخته‌ای می‌خوانند استفاده کن. بقیه را داده ساده بگذار. تعادل این‌جاست که ویژگی به‌جای جالب بودن، مفید می‌شود.

پرسش‌های کوتاه

کلاینت Prisma یا Drizzle را سریال کنم؟ نه. اتصال مال فرآیند است. شناسه را رد کن و در قدم بعد کلاینت را از نو بگیر.

اگر متد کلاس ایمیل بفرستد چه؟ آن متد اثر جانبی است و باید idempotent باشد. سریال کلاس این را تضمین نمی‌کند.

داده ساده همیشه بهتر نیست؟ برای بیشتر قدم‌ها چرا. کلاس را فقط وقتی اضافه کن که بدون آن، هر مرز پر از بازسازی تکراری همان دستگیره است.

Share this article

سریال کلاس در Workflow، TypeScript پایدار را کمتر آزاردهنده می‌کند | Mehd.ir