Получение ответа от HttpKernel для URL, распараллеленного
Я использую https://github.com/JosephSilber/page-cache для кэширования страниц. Для предварительной подготовки страниц (около 100 000) я использовал параллельный запуск 8 http-запросов через GuzzleHttp. Это работало, но было довольно медленно из-за накладных расходов.
Я ищу способ обработки экземпляра Illuminate\Http\Request
непосредственно через экземпляр приложения, предотвращая настоящий http-запрос. Я заметил, что это намного быстрее. Однако параллелизация этого с https://github.com/amphp/parallel-functions создает некоторые проблемы.
Основной код такой:
wait(parallelMap($urlChunks->all(), function($urls) {
foreach($urls as $url) {
//handle the request
}
}, $pool));
Я попробовал несколько вариантов обработки запроса.
1.
$request = \Illuminate\Http\Request::create($url, 'GET');
$response = app()->handle($request);
В этом случае app()
возвращает экземпляр Illuminate\Container\Container
, а не экземпляр приложения. Так что у него нет метода handle()
и так далее.
2.
$request = \Illuminate\Http\Request::create($url, 'GET');
$response = $app->handle($request);
Единственная разница здесь: переменная $app
был введен в закрытие. Его значение является правильным возвращаемым значением из app()
называется за пределами закрытия. Это приложение, но amp терпит неудачу, потому что соединения PDO, содержащиеся в экземпляре приложения, не могут быть сериализованы.
3.
$request = \Illuminate\Http\Request::create($url, 'GET');
$app = require __DIR__.'/../../../bootstrap/app.php';
$app->handle($request);
Это работает на короткое время. Но с каждым экземпляром приложения одно или два подключения mysql начинают задерживаться в состоянии "Сон". Они закрываются, только когда сценарий заканчивается. Важно: это не связано с распараллеливанием. Я фактически попробовал то же самое с последовательным циклом и заметил тот же самый эффект. Для меня это выглядит как ошибка в рамках, потому что следует ожидать, что экземпляр приложения закрывает все соединения, когда он разрушается. Или я могу сделать это вручную? Это был бы один из способов заставить эту вещь работать.
Есть идеи?
1 ответ
Третья версия - мой рекомендуемый способ сделать это. Ресурсы в PHP обычно очищаются, когда PHP существует, но это не работает для долго работающих приложений. Чтобы изменить это, я бы подал проблему в репозиторий Laravel или что-то еще, что создает соединение с базой данных.