Контроль виконання за допомогою Sleep Helper у Laravel

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 15 серпня, 2025
Досліджуйте, як помічник Sleep у Laravel може значно полегшити управління затримками у вашій логіці додатка, особливо при роботі з зовнішніми API. Читайте далі, щоб дізнатися, як реалізувати точний контроль часу для оптимізації виконання ваших команд

Функція Sleep у Laravel пропонує зручний спосіб впровадження контрольованих затримок у вашій логіці додатка. Цей інструмент є важливим для управління часом виконання, особливо в випадках, коли потрібно обережно регулювати темп через обмеження зовнішніх API або ресурсів.

Sleep забезпечує інтуїтивний флюентний інтерфейс для створення пауз у виконанні з точним контролем часу:

use Illuminate\Support\Sleep;

$attempts = 0;
$maxAttempts = 5;

while ($attempts < $maxAttempts) {
    $response = Http::get('https://api.example.com/status');

    if ($response->successful()) {
        break;
    }

    $attempts++;
    Sleep::for(2)->seconds();
}

Ця функція підтримує різні одиниці часу, включаючи секунди, мілісекунди, хвилини та мікросекунди, що дозволяє точно регулювати час для різних сценаріїв.

Розглянемо команду імпорту даних, яка обробляє великі CSV-файли, поважаючи системні ресурси та обмеження зовнішніх сервісів:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Sleep;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\DB;

class ImportCustomersCommand extends Command
{
    protected $signature = 'import:customers {file}';
    protected $description = 'Імпорт клієнтів з CSV файлу';

    public function handle()
    {
        $filePath = $this->argument('file');
        $customers = $this->readCsvFile($filePath);

        $this->info("Розпочато імпорт " . count($customers) . " клієнтів...");

        foreach ($customers as $index => $customerData) {
            $this->processCustomer($customerData);

            if (($index + 1) % 10 === 0) {
                $this->info("Оброблено " . ($index + 1) . " клієнтів");
                Sleep::for(1)->second();
            } else {
                Sleep::for(200)->milliseconds();
            }
        }

        $this->info('Імпорт успішно завершено!');
    }

    private function processCustomer(array $data): void
    {
        DB::transaction(function () use ($data) {
            $customer = Customer::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'phone' => $data['phone'],
            ]);

            if (!empty($data['company'])) {
                $this->validateCompany($data['company']);
                $customer->update(['company' => $data['company']]);
            }
        });
    }

    private function validateCompany(string $companyName): bool
    {
        $response = Http::timeout(10)->get('https://company-api.com/validate', [
            'name' => $companyName
        ]);

        if ($response->failed()) {
            Sleep::for(3)->seconds();
            return false;
        }

        Sleep::for(500)->milliseconds();
        return $response->json('valid', false);
    }

    private function readCsvFile(string $filePath): array
    {
        $customers = [];
        $handle = fopen($filePath, 'r');

        $headers = fgetcsv($handle);

        while (($row = fgetcsv($handle)) !== false) {
            $customers[] = array_combine($headers, $row);

            if (count($customers) % 100 === 0) {
                Sleep::for(100)->milliseconds();
            }
        }

        fclose($handle);
        return $customers;
    }
}

class ApiService
{
    public function fetchUserData(int $userId): ?array
    {
        $maxRetries = 3;
        $attempt = 0;

        while ($attempt < $maxRetries) {
            $response = Http::get("https://external-api.com/users/{$userId}");

            if ($response->successful()) {
                return $response->json();
            }

            if ($response->status() === 429) {
                $retryAfter = $response->header('Retry-After', 30);
                Sleep::for($retryAfter)->seconds();
            } else {
                Sleep::for(pow(2, $attempt))->seconds();
            }

            $attempt++;
        }

        return null;
    }

    public function batchSync(array $userIds): array
    {
        $results = [];

        foreach ($userIds as $index => $userId) {
            $userData = $this->fetchUserData($userId);

            if ($userData) {
                $results[] = $userData;
            }

            if ($index < count($userIds) - 1) {
                Sleep::for(1)->second()->and(500)->milliseconds();
            }
        }

        return $results;
    }
}

Функція Sleep легко інтегрується з тестовим фреймворком Laravel, що дозволяє перевіряти поведінку за часом без реальних затримок під час виконання тестів. Використовуйте Sleep::fake() для імітації викликів затримки та Sleep::assertSlept() для підтвердження очікуваної поведінки часу у вашій тестовій системі