PHP
Comments 38
+5
Собственно, почему бы и нет. Время идёт, PHP развивается. Только в глазах хейтеров он остаётся на том же уровне, что и был десяток лет назад.
0
Ох, помню опыт работы с Bunny. Тот еще ад в поддержке и внедрении чего-то. Используем React http в продакшене в качестве бекендов к api уже более двух лет. Не могу сказать, что все гладко и идеально, но много шишек уже набито и приложен подорожник. С учетом того, что вся инфраструктура масштабируется через rabbit, то stateless приложения дают ощутимый прирост производительности, нежели request-response
0
Спасибо за статью, в целом хороший экскурс в мир асинхронного PHP с тем для чего и как начать
0
Идите до дна. Вам нужен асинхронный режим работы с СУБД и весь ад, который оттуда вылезет.
+1
В статье всё указано, быть может недостаточно отчётливо, но всё же: взаимодействие с постгресом выполняется в асинхронном режиме.
0
Видел, но давайте уточню: у вас каждый SQL запрос к базе выполняется асинхронно?
0
Это круто, вы молодцы, но код будет как филиал ада ))
0
Давайте представим, что вам нужно либо добавить запись либо обновить. Для того, чтобы это понять, вам нужно проверить, есть ли такая запись в базе данных (по ID, например). Если записи нет, то сгенерировать sequence. То, что в PHP делается кодом в 4-6 строк, у вас станет на порядок больше (я помню, что на порядок это х10).
-2
Все здорово, только это синхронное программирование. А я говорю, что нужно идти до конца и выполнять SQL запросы асинхронно, т.е. промисами ждать, пока он выполнится и только потом продолжать выполнение логики.
+3

Вам нужно почитать статью от Никиты, тогда станет понятно откуда там взялся yield и почему код выглядит, как синхронный (каждый вызов execute и fetchOne возвращает Promise).


Мой косяк. Я не стал в статье углубляться в вопросы корутин и, вероятно, это повлияло на восприятие. Мне кажется, что вы имеете в виде callback hell, который мог бы случиться в случае, если бы я руками вызывал всю цепочку промисов.

0
Ага, разбираюсь, спасибо!
Идея понятна, удивительно, что я про такую возможность yield не подозревал (век живи..). Код, действительно, асинхронный и при этом красивый без всего этого чудовищного callback-а.
А транзакцию, подозреваю, вы передаете в $adapter?
0
Круто! Исключения тоже могут работать «в yield режиме»!
0

В этом и «фишка». Код, по сути, ни чем не отличается от привычного (даже вы сходу подвоха не разглядели). Знай себе, расставляй yield.

+1
Да, вы совершенно правы, огромное спасибо, что разъяснили!
0
Забавно, что можно использовать привычные библиотеки, модифицируя их по мере «асинхронизации» проекта
0

Нет, в этом плане так легко не получится.
Какую-нибудь Doctrine на асинхронные рельсы не поставить. Наоборот, привычные инструменты придётся очень сильно пересмотреть.

+1

А в чем проблема?
Код из проекта с Workerman+reactphp-mysql:


$account
            ->findUserByEmail($email)
            ->then(function($user) {
                if (!empty($user->id)) {
                    $exception = new\App\Exception\ValidationException("User Already Exist", 4);
                    $exception->setField("email");
                    throw $exception;
                }
            })
            ->then(function() use ($account, $email, $password) {
                $account->createUser($email, $password);
            })
            ->then(function() use ($email, $password) {
                $this->sendRegistrationEmail($email, $password);
            })
            ->then(function() use ($callback) {
                $this->sendAckSuccess(true, $callback);
            })
            ->otherwise(function(\Throwable $e) use ($callback) {
                $this->handleError($e, $callback);
            })
+2
А в чем проблема?

В этом примере? Огромное количество лишнего и ненужного кода, например =)

0

Какой код здесь лишний по-вашему?
function-обертки? От них можно избавиться при желании, получим что-то такое:


$account
    ->findUserByEmail($email)
    ->then([$this, "validateUserDoesNotExist"])
    ->then([$this, "createUser"])
    ->then([$this, "sendRegistrationEmail"])
    ->then([$this, "sendAckSuccess"])
    ->otherwise([$this, "handleError"])
;
+3

Мне удобнее писать:


$user = yield $account->findUserByEmail($email);

try {
    yield $this->validateUserDoesNotExist($user);
    yield $this->createUser($email, $password);
    yield $this->sendRegistrationEmail($email, $password);
    yield $this->sendAckSuccess(true, $callback);
} catch (\Throwable $e) {
    // ...
}

И автокомлит будет, и статический анализ, и меньше лишних then/otherwise

+1

удобнее так :)


        try
        {
            $userData = yield $repository->findUserByEmail($email);

            if(null === $userData)
            {
                yield $this->createUser($email, $password);
                yield $this->sendAckSuccess();
            }
        }
        catch(\Throwable $throwable)
        {
            /** ... */
        }
0

в данном примере проблемы 2:


  1. Это невозможно нормально читать;
  2. Подключение всего одно.

И если с первой проблемой можно (и нужно) бороться пакетом recoil, то вторая не позволит нормально работать. И что есть там асунк, что нету — ничего не меняется.

0
Вопрос, предположу, в следующем: у вас на все потоки одно подключение к БД?
0

Потоков в php не густо (всего 1). А вот как только будет 2 промиса, в рамках которых необходимо выполнить транзакции, будет ждать сюрприз.

0
Теоретически это легко разрулить собрав их в очередь и/или заведя пул подключений. Уверен есть библиотеки для этого.
+1
Простите, но это просто последовательный вызов функций. Хотелось бы увидеть работу с SQL, например, как вы тащите транзакцию через все это.
+1

Шикарная статья. Все понятно и разжевано. И полезно. Автору респект. И особенно порадовало сравнение с go в benchmarks.


Да это все велосипеды и т.д. И golang или rust предпочтительнее для таких задач. А для именно такой задачи — быстрее всего и устойчивее будет работать вообще erlang. Но имел я ввиду все это учить… (Это я абстрактно — го я знаю).


По факту все придет к унифицированным блокам (вход в бизнес логику — выход из логики) между которыми на чем вокер написан вообще плевать. Nginx Unit наглядный пример, кроме этого. А это — крупная компания, с бабками, не типа нас нищебродов...


Так что с точки зрения экономии времени на изучение этой библиотеки или golang — вывод очевиден.

Only those users with full accounts are able to leave comments.  , please.