Read-Through диски та Debounced Listeners у Laravel 13.26

Перекладено ШІ 0 Laravel News 20 серпня, 2026

Laravel 13.26 представляє драйвер файлової системи read-through та метод Queue::forward() для гнучкого перенаправлення черг. Оновлення також приносить покращення в Eloquent, підтримку Guzzle 8 та нові інструменти для дебаунсу Listeners і тестування Process.

Laravel 13.26 представляє новий драйвер файлової системи read-through, що дозволяє нашаровувати основний диск на резервний та копіювати файли при першому читанні. Також у релізі: функція debounce для queued event listeners та метод Queue::forward() для перенаправлення черг без зміни класів завдань. Команда Laravel випустила версію 13.26.0 18 серпня 2026 року.

  • Драйвер read-through для файлової системи з опціональним режимом без копіювання.
  • Атрибут #[DebounceFor] тепер підтримується для queued event listeners.
  • Queue::forward() дозволяє перенаправляти завдання в іншу чергу або на інше connection.
  • Ітеровані пули процесів, спеціальний виняток для idle timeout та нові fake assertions для Process.
  • Методи orWhereKey(), підтримка замикань у wherePivot() та використання enums у inOrderOf().
  • Подія JobReleased та сповіщення про призупинення черги у консолі worker.
  • Підтримка Guzzle 8 та серія виправлень для Redis cluster.

# Що нового

# Диски файлової системи Read-Through

Новий драйвер read-through об’єднує два диски в один. Система спочатку шукає файл на основному диску (primary), а якщо його там немає — звертається до резервного (fallback). Під час цього процесу файл автоматично копіюється на основний диск, що дозволяє поступово переносити лише затребувані дані. Операції запису, видалення та лістингу директорій виконуються лише на основному диску:

'assets' => [
    'driver' => 'read-through',
    'primary' => 'r2',
    'fallback' => 'legacy-s3',
],

Диски можна вказувати за назвою або описувати конфігураційним масивом безпосередньо в налаштуваннях. Опція copy => false дозволяє віддавати файли з резервного сховища без копіювання — це зручно для розробки, коли локальне середовище звертається до продакшн-файлів. Помилки копіювання за замовчуванням ігноруються, щоб не переривати читання; активувати їх можна параметром throw_on_promotion_failure => true.

Функціонал реалізовано @taylorotwell, а опцію no-copy додав @jimbojsb.

# Debounced Queued Listeners

Атрибут #[DebounceFor], який з'явився для queued jobs у Laravel 13.6, тепер доступний і для queued event listeners. Якщо одна й та сама подія спрацьовує кілька разів поспіль, обробник виконається лише один раз — після останнього виклику у вказаному вікні часу:

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Attributes\DebounceFor;

#[DebounceFor(30, maxWait: 120)]
class UpdateProductSearchIndex implements ShouldQueue
{
    public function debounceId(ProductUpdated $event): string
    {
        return (string) $event->product->getKey();
    }

    public function handle(ProductUpdated $event): void
    {
        // Переіндексація виконається один раз з актуальним станом
    }
}

Метод debounceId() обмежує дію затримки для конкретного ресурсу, а maxWait визначає максимальний час очікування, щоб постійний потік подій не відкладав роботу назавжди. Важливо: debounced listener не може одночасно реалізувати ShouldBeUnique, оскільки uniqueness зберігає перший виклик, а debouncing — останній.

Автор покращення — @stevebauman.

# Queue::forward()

Метод Queue::forward() дозволяє глобально перенаправляти всі завдання з однієї черги на іншу (або на інше з'єднання). Це налаштовується в одному місці (наприклад, у service provider) і не потребує змін у класах завдань чи місцях їх виклику:

use Illuminate\Support\Facades\Queue;

Queue::forward('reports', 'reports.fifo', 'cloud'); // Зміна назви та з'єднання
Queue::forward('payments', connection: 'cloud');    // Тільки зміна з'єднання
Queue::forward('updates', 'notifications');         // Тільки перейменування черги

Queue::forward([
    'reports' => 'reports.fifo',
    'emails' => 'emails.fifo',
], connection: 'cloud');

Перенаправлення працює через той самий хук, що і Queue::route(). Автор — @jackbayliss.

# Покращення роботи з Process

Фасад Process отримав три оновлення від @xurshudyan. Тепер пули процесів та їх результати підтримують ітерацію через foreach, оскільки класи реалізують IteratorAggregate.

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

try {
    Process::timeout(600)->idleTimeout(30)->run('./deploy.sh');
} catch (ProcessIdleTimedOutException $e) {
    // Немає виводу протягом 30 секунд: зупиняємо та сповіщаємо
} catch (ProcessTimedOutException $e) {
    // Процес працює, але занадто довго: даємо більше часу
}

Для тестування додано нові методи Process fake: assertRanCount() для перевірки кількості запущених процесів та assertRanInOrder() для перевірки послідовності команд.

# Нові можливості Eloquent Builder

Додано методи orWhereKey() та orWhereKeyNot(), що спрощують запити, де умова за первинним ключем має бути частиною гілки or.

Метод wherePivot() тепер приймає замикання з екземпляром builder, що дозволяє використовувати scope-методи безпосередньо на кастомних моделях зв'язку (pivot classes):

$project->subscribers()
    ->wherePivot(fn ($query) => $query->active()->notMuted())
    ->get();

Метод inOrderOf() тепер підтримує enums у списку значень:

$orders = Order::query()
    ->inOrderOf('status', [Status::Pending, Status::Processing, Status::Shipped])
    ->get();

# Прозорість роботи Queue Worker

Нова подія JobReleased спрацьовує, коли завдання повертається в чергу через власний обробник або middleware (наприклад, WithoutOverlapping). Раніше існувала лише подія JobReleasedAfterException, тому випуски завдань без помилок були "невидимими" для системи моніторингу.

Крім того, worker тепер виводить повідомлення, коли черга призупиняється або відновлює роботу. Це допомагає зрозуміти, чи worker завис, чи він просто очікує активації черги.

# Інші виправлення та покращення

  • Додано підтримку Guzzle 8.
  • Команда db:seed --class тепер відображає прогрес виконання (RUNNING/DONE).
  • Покращено стабільність роботи з Redis cluster: виправлено перевірку призупинених черг, очищення тегів кешу та роботу коннекцій після збоїв у pipeline.
  • У хмарному драйвері черг додано доступ до managedQueues() та автоматичне повторення long-polls при таймаутах.
  • Виправлено логіку throwUnless() та збереження порядку ключів у Request при об'єднанні файлів.
  • Усунено помилки у роботі з Microsoft SQL Server, Postgres JSON path та JSON:API параметрами.
  • Оптимізовано реєстрацію команд pail та artisan dev.

Примітки щодо оновлення

Для більшості застосунків оновлення пройде непомітно. Зверніть увагу на два моменти: поєднання #[DebounceFor] та ShouldBeUnique тепер викликає LogicException, а внутрішня логіка whereKey() була консолідована, що може вплинути на вас лише у разі перевизначення цих методів у кастомному Eloquent builder.

Посилання

Популярні

Інше, що варто прочитати

26 Оновлено 26 червня, 2026

Створення MCP-серверів на PHP

Модельний контекстний протокол (MCP) відкриває нові горизонти в інтеграції AI-додатків з PHP. Дізнайтеся, як легко створити сервер, що відповідає MCP, та які можливості відкриваються для вашого проєкту

13 Оновлено 26 червня, 2026

Створення CLI-додатка за допомогою Laravel та Docker

Зазирніть у світ Laravel, де потужний CLI-фреймворк відкриває нові можливості для розробки командного інтерфейсу. Дізнайтеся, як створити просту утиліту для перевірки акцій, яка працює з Docker, та які переваги це може принести у вашому проєкті!

51 Оновлено 26 червня, 2026

Nuxt 3 + Laravel Sanctum: Просте та надійне рішення для автентифікації вашого SPA та API

У сучасній веб-розробці аутентифікація є ключовою для захисту додатків і даних користувачів. Дізнайтеся, як модуль nuxt-sanctum-authentication спростить інтеграцію між Nuxt 3 та Laravel Sanctum, забезпечуючи надійний і зручний спосіб реалізації аутентифікації для вашого проєкту