Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 19 серпня 2026

Laravel Chores: відновлювані операції з даними та автоматизація рутинних завдань

Новий пакет Laravel Chores від Amr Lotfy Saleh розв'язує типову проблему масових операцій з даними: коли обробка мільйонів записів перервалася через перезапуск сервера, важко визначити, на якому саме записі зупинилися. Пакет обгортає одноразові операції з даними в пачки (batches), які зберігають прогрес у базі даних після кожної пачки. Якщо процес переривається, наступний запуск продовжить роботу з того місця, де зупинився, замість того щоб починати спочатку. Дизайн пакету натхненний гемом maintenance_tasks для Rails від Shopify.

Ключові можливості

Пакет надає такий функціонал:

  • Збереження прогресу (checkpointed progress) - ID останнього обробленого запису записується в таблицю chore_runs після кожної пачки, тому аварійне завершення або Ctrl+C втрачає максимум одну пачку прогресу
  • Keyset pagination - пачки обробляються за первинним ключем, а не за offset, що уникає класичної помилки, коли оновлення рядків зміщує їх з частини, яку ви ітеруєте
  • Ізоляція помилок - запис, що викликає виняток, логується в таблицю збоїв і пропускається, а виконання продовжується
  • Без додаткової інфраструктури - стан зберігається у вашій базі даних, без потреби в Redis, queue workers або зовнішніх сервісах
  • Шість Artisan-команд - створення шаблону, запуск, список, пауза, перегляд збоїв та повторна спроба
  • CI-friendly вивід - режим JSON-виводу та чіткі коди виходу: 0 для чистого завершення, 1 для завершення зі збоями, 2 для фатальної помилки

Створення Chore

Chore - це клас з двома методами: collection() повертає запит для записів, які потрібно обробити, а process() обробляє один запис. Створити шаблон можна командою php artisan make:chore:

namespace App\Chores;

use AmrLotfy\Chores\Chore;
use App\Models\User;
use Illuminate\Contracts\Database\Eloquent\Builder;

class NormalizePhoneNumbers extends Chore
{
    public int $batchSize = 500;

    public function collection(): Builder
    {
        return User::whereNotNull('phone')
            ->where('phone', 'not like', '+%');
    }

    public function process($record): void
    {
        $record->update([
            'phone' => PhoneNumber::parse($record->phone, 'EG')->toE164(),
        ]);
    }
}

Це весь клас. Розбиття на пачки, відстеження прогресу та логування помилок відбуваються автоматично. Розмір пачки за замовчуванням становить 500 записів через конфігураційний файл, якщо ви не вказали його в класі.

Запуск, пауза та відновлення

Команда chore:run виконує chore з відображенням прогресу в реальному часі в терміналі:

php artisan chore:run NormalizePhoneNumbers

Прогрес зберігається після кожної пачки, тому та сама команда відновлює виконання, яке було перерване через deploy, аварію або Ctrl+C. Команда chore:pause зупиняє виконання на межі наступної пачки, а chore:list показує доступні chores разом з історією їх виконання.

Одне застереження щодо гарантій: збереження прогресу відбувається після пачки, а не після окремого запису, тому записи всередині пачки, яка виконувалась під час переривання, можуть бути повторно перевірені після відновлення. По можливості пишіть process() ідемпотентним - наведений вище приклад з номерами телефонів безпечний, оскільки вже нормалізовані номери більше не відповідають запиту collection().

Для регулярних завдань, таких як очищення застарілих записів, можна використовувати команду разом з планувальником завдань Laravel:

$schedule->command('chore:run PurgeExpiredRecords')->monthly();

Обробка помилок

Запис, що викликає виняток, не зупиняє виконання. Пакет логує запис і виняток у таблицю збоїв, пропускає його та продовжує роботу. Коли виконання завершується, ви можете переглянути та повторно обробити записи зі збоями як окрему операцію:

php artisan chore:failures NormalizePhoneNumbers
php artisan chore:retry NormalizePhoneNumbers

Такий підхід важливий для тривалих операцій: сотня некоректних номерів телефонів з десяти мільйонів не повинна зупиняти чотиригодинне завдання, а повторна обробка сотні записів після виправлення набагато дешевша, ніж повторне виконання всього процесу.

Технічні особливості та обмеження

Chores виконуються на передньому плані з одним воркером на chore, а колекція потребує упорядковуваного первинного ключа, такого як auto-increment або ULID. Виконання в черзі та паралельні воркери знаходяться в дорожній карті; якщо ви хочете розподілити масове оновлення між queue workers вже сьогодні, пакет Queue-SQL використовує такий підхід.

Встановлення

Laravel Chores вимагає PHP 8.2+ та Laravel 12 або 13, підтримує MySQL, PostgreSQL та SQLite:

composer require amrlotfy/laravel-chores
php artisan vendor:publish --tag=chores-migrations
php artisan migrate

Конфігураційний файл дозволяє змінити місце розташування класів chore (за замовчуванням app/Chores), розмір пачки за замовчуванням, назви таблиць та інтервал паузи між пачками для зменшення навантаження на завантажену базу даних.

Вихідний код, документацію та дорожню карту можна знайти в репозиторії Laravel Chores на GitHub.

5

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Новини 27 жовтня 2026

Filament v5.11.0: поля й віджети на React, Vue і Svelte та жорсткіший захист Livewire

Filament v5.11.0 дозволяє писати власні поля форм, компоненти схем і віджети на React, Vue, Svelte або чистому JavaScript. Паралельно v5.11.0 і v4.16.0 закривають для клієнта внутрішні Livewire-методи та стан і додають опційні ліміти для репітерів і пагінації таблиць.

2
Новини 27 жовтня 2026

Livewire 4.4.8 закриває обхід #[Authorize], а NativePHP Mobile - сім вразливостей

Livewire 4.4.8 виправляє GHSA-mhf7-xp6r-6qrc (CVSS 6.5): атрибут #[Authorize] можна було обійти й виконати дію над чужим записом. Того ж тижня NativePHP опублікувала сім попереджень для NativePHP for Mobile - виправлення в nativephp/mobile 4.6.1 і 3.3.11, але до користувачів вони дійдуть лише з новою збіркою застосунку.

1

Вакансії за темою

Wooden Sword
30 днів тому

Senior PHP Developer (Game Backend)

Розробник backend для мобільної RPG з високим навантаженням. Основний стек: PHP Laravel API та TypeScript Nakama Game Server. Відповідальність за повний цикл розробки функцій — від логіки до тестування, code review, оптимізації та документації. Вимоги: 5+ років backend-досвіду, бездоганне знання Laravel/PHP, сильні навички TypeScript, PostgreSQL та асинхронного програмування.

levari Нова
Вчора

Senior Laravel Developer (Statamic), German-speaking preferred

Розробник на тривалий проєкт для клієнта німецького digital-агентства: оновлення існуючого сайту та екстранету на Statamic, зокрема великий апгрейд платформи до кінця листопада, далі розробка нових функцій. Ключовий стек: Laravel, Statamic, автентифікація та складна модель ролей і дозволів. Вимоги: понад 5 років комерційного досвіду з Laravel, досвід оновлення продакшн-застосунків, самостійність, робота з німецької IP-адреси через VPN. Бажано Vue.js та німецька від B2.

Middle Backend Engineer PHP/Laravel

Розробка бекенду для нової платформи запису й редагування відео з AI: REST API для керування контентом (S3-завантаження, метадані, мініатюри, планування), оркестрація задач обробки відео на AI-воркерах RunPod, інтеграції з платежами, аналітикою та AI-сервісами, WebSocket-синхронізація з клієнтами та фонові черги. Потрібен досвід із бекенд-фреймворками, проєктуванням баз даних, автентифікацією й безпекою API, роботою з вебхуками та Docker, Git і CI/CD.

Пакети за темою

Bagisto

bagisto/bagisto

Bagisto — це платформа для електронної комерції, побудована на Laravel. Вона надає готове рішення для створення та управління інтернет-магазинами з підтримкою каталогу товарів, замовлень, платежів та клієнтів.

28,282 v2.5.0 13 26

Lang

laravel-lang/lang

Список 126 мов для Laravel Framework, Laravel Jetstream, Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova, Laravel Spark та Laravel UI.

7,780 15.37.4 12