Кожен розробник писав код, який мав бути тимчасовим — швидкий обхід перед демо, feature-flag для поступового розгортання або заглушка в очікуванні виправлення від постачальника. Проблема в тому, що TODO-коментарі зариваються, таски забуваються, а «тимчасовий» код стає постійним.
Laravel Deadlock — пакет від Med Mahmoud Hdaya, який вирішує це, дозволяючи позначати тимчасові обходи явними датами закінчення через PHP-атрибути. Коли дедлайн минає, пакет забезпечує відповідальність: у середовищі розробки кидає runtime-виключення, а в CI/CD — провалює збірку.
Як це працює
Позначення коду для перегляду
Додайте атрибут #[Workaround] до класу або методу, який плануєте переглянути. Вкажіть опис, чому код тимчасовий, та дату закінчення.
Наприклад, позначення методу контролера під час міграції API:
use Zidbih\Deadlock\Attributes\Workaround;
class PaymentController extends Controller
{
#[Workaround(
description: 'Використовується старий Stripe API v2, доки оновлення до v3 не завершене',
expires: '2026-01-05'
)]
public function processPayment(Request $request)
{
// Тимчасовий обхід за допомогою застарілого API
return $this->legacyStripeService->charge($request->amount);
}
}
Можна також позначати цілі класи — корисно для feature-flagів або застарілих шляхів коду:
use Zidbih\Deadlock\Attributes\Workaround;
#[Workaround(
description: 'Прибрати застарілу панель після міграції всіх користувачів',
expires: '2026-02-15'
)]
class LegacyDashboardController extends Controller
{
// Стара реалізація панелі, яку потрібно видалити
}
Перелік тимчасового коду
Запустіть php artisan deadlock:list, щоб просканувати весь тимчасовий код у проєкті:
+---------+------------+-------------------------------------+---------------------------------------------------+
| Статус | Закінчується | Місцезнаходження | Опис |
+---------+------------+-------------------------------------+---------------------------------------------------+
| EXPIRED | 2026-01-05 | PaymentController::processPayment | Використовується старий Stripe API v2, доки оновлення до v3 не завершене |
| OK | 2026-02-15 | LegacyDashboardController | Прибрати застарілу панель після міграції всіх користувачів |
| OK | 2026-01-20 | CacheAdapter::get | Тимчасовий обхід Redis, поки не виправлять драйвер кешу |
+---------+------------+-------------------------------------+---------------------------------------------------+
Ця команда допомагає системно відстежувати технічний борг. Під час планування спринту чи code review видно, що потребує уваги.
Примусове дотримання дедлайнів
Laravel Deadlock розрізняє середовища розробки й продакшн. У локальній розробці виконання коду з простроченим дедлайном кидає виняток, блокуючи подальшу роботу, доки дедлайн не продовжать або не виправлять проблему. У продакшні runtime-примус вимкнений, щоб не впливати на користувачів.
Для автоматичної перевірки в CI/CD додайте команду в пайплайн:
# .github/workflows/tests.yml
name: Tests
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
- name: Checkout Code
uses: actions/checkout@v4.1.7
- name: Install dependencies
run: composer install
- name: Check for expired deadlocks
run: php artisan deadlock:check
- name: Run tests
run: php artisan test
Якщо знайдено прострочені обходи, збірка повертає exit code 1, і деплой не відбудеться, поки команда не усуне технічний борг.
Вивід може виглядати так:
Expired workarounds detected:
- Прибрати застарілу панель після міграції всіх користувачів | expires: 2026-02-15 | LegacyDashboardController
- Тимчасовий обхід Redis, поки не виправлять драйвер кешу | expires: 2026-01-20 | CacheAdapter::get
Примусова перевірка під час виконання для сервісів
Контролери перевіряються автоматично, а сервіси й інші класи потребують явного виклику. Використайте DeadlockGuard::check(), щоб перевіряти термін дії при інстанціюванні класу:
use Zidbih\Deadlock\Attributes\Workaround;
use Zidbih\Deadlock\Support\DeadlockGuard;
#[Workaround(description: 'Тимчасова застаріла логіка ціноутворення', expires: '2026-02-01')]
final class PricingService
{
public function __construct()
{
DeadlockGuard::check($this);
}
}
Для перевірки на рівні методу передайте ім'я методу другим аргументом: DeadlockGuard::check($this, __FUNCTION__).
Практичні випадки використання
Laravel Deadlock добре підходить для типових сценаріїв:
- Видалення feature-flagів: позначайте feature-flag-и дедлайнами, прив’язаними до завершення розгортання
- Міграція API: відстежуйте тимчасові адаптери або compatibility-слої під час оновлення постачальника
- Застаріла функціональність: ставте дедлайни на видалення старого коду після міграції користувачів
- Післярелізне прибирання: позначайте швидкі фікси, зроблені під час інцидентів, датами для подальшого очищення
- Експерименти з обмеженим терміном: задавайте явні дедлайни для оцінки фічі
Встановити Laravel Deadlock через Composer:
composer require zidbih/laravel-deadlock
Пакет потребує PHP 8.2 або вище та сумісний із Laravel 10, 11 і 12. Дивіться репозиторій на GitHub для повної документації та коду.