Comments 44
Дико извиняюсь за хейт, ведь сейчас любая неудобная критика -- это хейт? А критика неудобная.
По факту спустя несколько лет после выпуска статьи ничего не изменилось. Не нужно брать PHP, если требуется хорошая работа с асинхронным IO и эффективная работа (в едином процессе). Плохой он для этого. И дело не в языке даже, а в изначально заложенной парадигме, существующих решений и библиотеках.
Для всего нужны какие-то костыли и припарки. Тот же RR это костыли на Go. Зачем они? Почему бы сразу не писать на Go?
Я всё понимаю. PHP высокоуровневый, и разработчик на PHP стоит дешевле, чем на Go, Java, .NET. И для большинства довольно простых ненагруженных проектов это выгодно. Но на этом преимущества заканчиваются. Очень много каких-то колоссальных приседаний, чтоб вот PHP работал как компилируемое однопроцессное приложение. Вижу, что в этом направлении потихоньку движется. Но зачем? Почему бы не выжимать из него максимум там, где он хорош?
Мысли не с потолка, они грустные, так как вижу вплотную сколько страданий там, где их вообще нет в других языках. Где хранить метрики? Почему образы конские? Как бы так сбрасывать телеметрию, чтоб не влиять на время запроса? Почему отваливаются консьюмеры очередей? Почему концепция один контейнер = один процесс не работает? Фиг бы с этими "почему", я же просто очередной хейтер.
Писать глупости с позиции жертвы - довольно занятная манипуляция.
По факту спустя несколько лет после выпуска статьи ничего не изменилось"
Файберы с вами не согласятся.
разработчик на PHP стоит дешевле, чем на Go, Java, .NET. И для большинства довольно простых ненагруженных проектов это выгодно.
Это миф, который уже лет ентак 10 как не имеет никакой связи с реальностью.
Вижу, что в этом направлении потихоньку движется
где вы это видите и не нужно ли сходить к окулисту на всякий случай?
Где хранить метрики
Почему образы конские
Как это относится к языку программирования?
Как бы так сбрасывать телеметрию, чтоб не влиять на время запрос
Точно так же, как в любом другом ЯП
Почему отваливаются консьюмеры очередей
Потому же, почему и в go/java/kotlin/whatever
Почему концепция один контейнер = один процесс не работает
В вашей картине мира, вполне вероятно, что не работает.
Фиг бы с этими "почему", я же просто очередной хейтер.
платочек передать?
Я прекрасно знал, что отхвачу минусов.
И демагогию разводить не хочу. Много раз дискутировал с PHP-шниками, и много раз всё сводилось к тому, что это я дурак и ничего не понимаю, при чём PHP-шники зачастую крайне агрессивные, яркий пример ваше "и не нужно ли сходить к окулисту на всякий случай".
платочек передать?
Да, передайте пожалуйста. У меня действительно слёзы боли. Ибо имею с проектами PHP тесный контакт. И такого количества совершенно детских проблем я не видал нигде. Подчёркиваю. Ни-где.
Можете мне рассказывать конечно про волшебные файберы, про "это фсё миф 10 лет как", волшебный сказочный мир, который я бы очень хотел, чтоб был реальностью.
А в реальности проекты PHP это какие-то постоянные превозмогания, боль и страдания.
Почему отваливаются консьюмеры очередей
Потому же, почему и в go/java/kotlin/whatever
Нет, нигде больше не отваливаются. Это просто один из множества примеров множества проблем. Думаете меня это радует? Ничуть. Так что давайте свой платочек.
Если они нигде больше не отваливаются, то почему бы им начать отваливаться в php? Ваша аргументная база просто поражает, не удивительно, что результат ваших "дискуссий" всегда един.
И чем таким я умудрился вас оскорбить или обидеть, что вы таким образом со мной начали общаться? Это комплекс какой-то? Или так принято в среде PHP-сообщества, и это норма, вести себя по-хамски и высокомерно, если что-то не укладывается в вашу картину мира? А вы именно так себя ведёте.
Писать глупости с позиции жертвы - довольно занятная манипуляция.
платочек передать?
О какой дискуссии может быть речь?
Я высказал своё мнение, основываясь на 3-х летнем наблюдении за развитием и прямой поддержкой проектов на PHP. Для начала, если PHP пытается стать как Go, используя костыли на Go, то это не нужно. И по нашему коллективному опыту выглядит и работает это плохо. И сравнить есть с чем.
https://gist.github.com/mmasiukevich/b7484b90a01046df4919dbf1c99912b9
Не вижу особой разницы, если честно. А если ещё перестать пользоваться sequence в пользу uuid, совсем проще будет.
Вам нужно почитать статью от Никиты, тогда станет понятно откуда там взялся yield
и почему код выглядит, как синхронный (каждый вызов execute
и fetchOne
возвращает Promise
).
Мой косяк. Я не стал в статье углубляться в вопросы корутин и, вероятно, это повлияло на восприятие. Мне кажется, что вы имеете в виде callback hell, который мог бы случиться в случае, если бы я руками вызывал всю цепочку промисов.
yield
is used to “await” promises, yield from
can be used to delegate to a sub-routine. yield from
should only be used to delegate to private methods, any public API should always return promises instead of generators.
Идея понятна, удивительно, что я про такую возможность yield не подозревал (век живи..). Код, действительно, асинхронный и при этом красивый без всего этого чудовищного callback-а.
А транзакцию, подозреваю, вы передаете в $adapter?
С точки зрения транзакций есть 2 варианта использования:
Привычный для тех, кто пользовался, например, Doctrine (метод transactionl): https://gist.github.com/mmasiukevich/722f87f6ec657a00b782cb646233dec0
и обычный: https://gist.github.com/mmasiukevich/c2eb86974cc0a0b2787734e0196d6ec2
В этом и «фишка». Код, по сути, ни чем не отличается от привычного (даже вы сходу подвоха не разглядели). Знай себе, расставляй yield
.
А в чем проблема?
Код из проекта с 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);
})
А в чем проблема?
В этом примере? Огромное количество лишнего и ненужного кода, например =)
Какой код здесь лишний по-вашему?
function-обертки? От них можно избавиться при желании, получим что-то такое:
$account
->findUserByEmail($email)
->then([$this, "validateUserDoesNotExist"])
->then([$this, "createUser"])
->then([$this, "sendRegistrationEmail"])
->then([$this, "sendAckSuccess"])
->otherwise([$this, "handleError"])
;
Мне удобнее писать:
$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
в данном примере проблемы 2:
- Это невозможно нормально читать;
- Подключение всего одно.
И если с первой проблемой можно (и нужно) бороться пакетом recoil, то вторая не позволит нормально работать. И что есть там асунк, что нету — ничего не меняется.
Если вам не нравятся function-обертки, то ответил тут: https://habr.com/ru/post/451916/#comment_20158824
Если какие-то другие претензии к читабельности, то не могли бы вы описать подробнее?
Подключение всего одно.
И?
Потоков в php не густо (всего 1). А вот как только будет 2 промиса, в рамках которых необходимо выполнить транзакции, будет ждать сюрприз.
Шикарная статья. Все понятно и разжевано. И полезно. Автору респект. И особенно порадовало сравнение с go в benchmarks.
Да это все велосипеды и т.д. И golang или rust предпочтительнее для таких задач. А для именно такой задачи — быстрее всего и устойчивее будет работать вообще erlang. Но имел я ввиду все это учить… (Это я абстрактно — го я знаю).
По факту все придет к унифицированным блокам (вход в бизнес логику — выход из логики) между которыми на чем вокер написан вообще плевать. Nginx Unit наглядный пример, кроме этого. А это — крупная компания, с бабками, не типа нас нищебродов...
Так что с точки зрения экономии времени на изучение этой библиотеки или golang — вывод очевиден.
Асинхронный PHP и история одного велосипеда