Задать вопрос
@Nolan81
программист

Как точно работает скрипт на RoadRunner?

Привет.
У меня есть такой скрипт, который крутится на RR
use Nyholm\Psr7;
use Psr\Http\Message\ServerRequestInterface;
use Spiral\RoadRunner;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\JsonResponse;

$worker = RoadRunner\Worker::create();
$psrFactory = new Psr7\Factory\Psr17Factory();

$worker = new RoadRunner\Http\PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory);
$router = new League\Route\Router;


while ($req = $worker->waitRequest()) {
    $response = "";
    try {
        $post = $req->getParsedBody();
        $path = $req->getUri()->getPath();
        $router->map('POST', '/some1[/]', function (ServerRequestInterface $req, array $args) {
//...
}
       $router->map('POST', '/some2[/]', function (ServerRequestInterface $req, array $args) {/**/}

        $response = $router->dispatch($req);

        $worker->respond($response);
    } catch (League\Route\Http\Exception\MethodNotAllowedException $e) {
        $worker->respond(new HtmlResponse('<b>Error</b>: ' . $e->getMessage(), 500));
    } catch (League\Route\Http\Exception\NotFoundException $e) {
        $worker->respond(new HtmlResponse('<b>Error</b>: ' . $e->getMessage(), 404));
    } catch (\Throwable $e) {
        //моя обработка
    }
}


Мне не понятны пару вопросов:
1) какая часть скрипта выполняется один раз при старте воркера, а какая часть при каждом запросе от пользователей?
Все что внутри while ($req = $worker->waitRequest()) { - этот код выполняется для каждого запроса, а то что снаружи - один раз?
2) гпт говорит что не надо $router->map( ) внутри этого цикла waitRequest делать, это так? (скрипт унаследован от предыдущего разработчика, разбираюсь с ним)
3) как лучше с БД работать?
В глобальной части, до while ($req = $worker->waitRequest()) {, открыть соединение?
А внутри цикла, проверять актуальность, вот так?:
$connOk = false;
        try {
/* @var \mysqli $sql*/
            $connOk = @mysqli_ping($sql);
        } catch (\Throwable $e) {

        }
        if (!$connOk) {
            if (!empty($sql) && $sql instanceof \mysqli) {
                @mysqli_close($sql);
            }
            $sql = mysqli_connect(/**/);
        }
  • Вопрос задан
  • 115 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
Vamp
@Vamp
  1. Верно. Такой подход называется event loop.
  2. Тоже верно. Настраивать роутер нужно один раз.
  3. Да. Только вместо mysqli_ping нужно использовать mysqli_change_user.

    Функция mysqli_ping помечена как deprecated и документация php настоятельно рекомендует её не использовать.

    Функция mysqli_change_user помимо того, что валидирует соединение, ещё очищает его от состояния, оставшегося от предыдущего http запроса - откатывает незавершённые транзакции, сбрасывает сессионные переменные, снимает разнообразные локи и т.д. Это довольно важный момент, который защитит вас от трудноуловимых ошибок, когда http запрос может оказывать влияние на следующий, казалось бы, независимый http запрос.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы