لاراول 13.40: هشدار برای jobهای طولانی و رفع یه باگ امنیتی
خلاصهٔ کاملتر
تیم لاراول نسخه 13.40.0 رو منتشر کرده. مهمترین قابلیت جدیدش Queue::whenJobRunsLongerThan() هست که وقتی یه تلاش برای اجرای job از یه حد زمانی بیشتر طول بکشه، یه callback اجرا میکنه. این callback به رویداد JobAttempted گوش میده، پس برای تلاشهای fail شده یا release شده هم اجرا میشه. اگه عدد خالی بدی، میلیثانیه حساب میشه:
Queue::whenJobRunsLongerThan(CarbonInterval::seconds(90), function ($job, $duration) {
Log::warning("{$job->resolveName()} took {$duration}ms");
});یه متد مشابه هم به اسم Schedule::whenTaskRunsLongerThan() برای تسکهای زمانبندیشده اومده که بعد از تموم شدن یا fail شدن تسک اجرا میشه، ولی اینجا عدد خالی ثانیه حساب میشه.
برای read replica (یعنی سرور دیتابیس کپی که فقط برای خوندن استفاده میشه) متدهای DB::getLastCommitId() و DB::hasCommitId() اضافه شدن. بعد از نوشتن روی سرور اصلی commit ID رو میگیری و بعداً روی replica چک میکنی که رسیده یا نه، حتی میتونی تا چند ثانیه منتظر بمونی. یعنی دیگه لازم نیست مثل middleware قبلی PreventStaleDatabaseReads حدس بزنی تأخیر replica چقدره. این قابلیت روی MySQL با GTID، MariaDB با binary log و PostgreSQL کار میکنه و برای انتظار روی PostgreSQL نسخه 19 لازمه.
تو فایل bootstrap/app.php حالا متدهای insertBefore() و insertAfter() هست که middlewareت رو دقیقاً قبل یا بعد از یکی از middlewareهای پیشفرض لاراول میذارن، بدون اینکه کل stack رو دستی تعریف کنی. نسخههای insertBeforeInGroup() و insertAfterInGroup() هم برای گروههایی مثل web هست. یه پارامتر strict هم به integer()، float()، boolean() و string() اضافه شده که مقدار نامعتبر رو بهجای تبدیل عجیب، با مقدار پیشفرض جایگزین میکنه:
// ?count=abc123
$request->integer('count', 5); // 0
$request->integer('count', 5, strict: true); // 5بخش امنیتی این نسخه مهمه. تو Concurrency::run() با درایور پیشفرض process، پروسه والد نتیجه تسک رو از خروجی پروسه فرزند میخوند و unserialize میکرد (یعنی رشته رو دوباره به آبجکت PHP تبدیل میکرد). اگه تسک متنی رو چاپ میکرد که دست کاربر بود، میشد یه نتیجه جعلی ساخت و به اجرای کد از راه دور رسید. حالا نتیجه با یه کلید تصادفی مخصوص هر تسک امضا میشه و والد هر چیز بدون امضای معتبر رو نادیده میگیره. اگه از این قابلیت استفاده میکنی، باید آپدیت کنی.
دو مشکل transaction هم رفع شده: اگه وسط transaction اتصال قطع بشه، لاراول حالا اتصال مرده رو کنار میذاره و دوباره وصل میشه، در حالی که قبلاً تا ریاستارت worker یا Octane همه transactionها با خطا مواجه میشدن. Lock wait timeout یا deadlock تو transaction تودرتو هم حالا به savepoint همون transaction برمیگرده. خروجی queue:work هم برای jobهای برگشته به صف بهجای DONE حالا RELEASED نشون میده.
نکات کلیدی:
- Queue::whenJobRunsLongerThan() عدد خالی رو میلیثانیه و Schedule::whenTaskRunsLongerThan() ثانیه حساب میکنه
- DB::hasCommitId() روی MySQL با GTID، MariaDB و PostgreSQL کار میکنه؛ بقیه درایورها RuntimeException میدن
- انتظار برای commit ID روی PostgreSQL به نسخه 19 نیاز داره
- تو حالت strict، متد boolean() فقط مقادیری مثل 1، true، on، yes و معادلهای منفیشون رو قبول میکنه
- رفع آسیبپذیری اجرای کد از راه دور در Concurrency::run() با درایور process (PR شماره 62297)




