Функція 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()
для підтвердження очікуваної поведінки часу у вашій тестовій системі