Pull to refresh

Comments 16

Скоро у нас будет свой полноценный веб-сервер

Поскольку одновременно может выполняться только один файбер, у вас не возникнет чего-то вроде состояния гонки, когда к памяти обращается сразу два потока.


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

По моему это обертка над корутинами и генераторами, которые были добавлены еще в php 5.5. Что я могу сделать с помощью файберов такого, что не смогу сделать с корутинами и генераторами?

Идея в том, что все IO операции вы выполняете асинхронно. Таким образом если в вашем приложении весь код асинхронный, то запуск одного процесса позволит обрабатывать сколько угодно подключений, пока хватает одного ядра процессора.


Если не хватает одно ядра, то опять же не беда — можете использовать балансировщик, или прямо опцию SO_REUSEPORT, чтобы расширить один сокет на несколько процессов.


Файберы не дают принципиально нового функционала, всё это уже сейчас можно делать в amphp, reactphp, swoole (включая http-сервер, кстати). И это действительно круто работает (у меня в проде, по крайней мере). Файберы дают возможность писать чистый код, значительно более чистый, который без них или аналога принципиально невозможен в PHP.

Файберы дают возможность писать чистый код, значительно более чистый, который без них или аналога принципиально невозможен в PHP.


Можете поделиться мини-примером такого принципиально невозможного кода(обычный php+fiber). Пример с этой страницы без проблем переделывается под корутину и генератор.

ну как минимум файберы дадут возможность нормально указывать возвращаемый тип, а не Generator / Amp\Promise, в который заворачивается результат.
кроме того, вероятно, появится возможность более изящно использовать асинхроный код в синхронной среде, чем сейчас — Amp\Promise\wait(Amp\call(fn () => yield $coroutine));

Как например: await в виде функции, а не через обёртку с колбеком с yield'ом (как это сейчас в amphp).
Конечно, php в чистом виде не способен решать задачи, которые распараллеливаются для достижения максимальной скорости выполнения, но для параллельных задач, где задержка в пару секунд не играет роли (например отправить 1000 email-ов) прекрасно подходит пул воркеров разгребающих задачи из очереди, либо когда создаем много воркеров(каждый под свою задачу) и менеджер воркеров сам контролирует каждый процесс и если нужно перезапустит упавших.

Зависит от объема. Я на хабре уже писал про это в комментариях. При этом совершенно не важно разбираете вы задачи из очереди или генерируете их на лету.


Условная задача — отправить 10 млрд http-запросов. Время ответа сервера на запрос — 30 секунд. Условный веб-сервер обрабатывающий ваши запросы согласен обрабатывать их в любом количестве, там нет узкого места.


Прямо сейчас не погружаемся в асинхронные библиотеки, используем встроенный в пхп функционал:
Синхронно — curl
Асинхронно — curl_multi


Производительность второго решения будет значительно выше. Можете побенчить, на таких условиях для синхронного решения у вас больше половины ресурсов сервера будет уходить в kernel usage на переключение контекста (либо будет недогружен CPU).

Зависит от объема.

и от задачи, на одних http запросах параллельные задачи не заканчиваются ))

А если бы у вас стояла задача отправить отправить 10 млрд http-запросов(время ответа не константа), распарсить ответ, сделать N запросов в бд, то вы никуда не денетесь от того, что обрабатывать запросы все равно будет синхронно (хоть и выполняться они будут асинхронно). И тут, на мой взгляд, уже пул воркеров может справится лучше
Нет, асинхронный код справится быстрее на тех же CPU. Запросы в БД (предполагаю, что в ресурсы сервера базы мы не упираемся, иначе это другая задача — про оптимизацию базы) — это тоже IO, они тоже идут в eventloop. Тут наоборот, чем больше у вас потоков IO — тем более эффективен подход с eventloop.

Если вы хотите свести задачу к CPU-bound (скажем парсинг ответа занимает 30 секунд полностью съеденного ядра процессора, но это простите уже совсем другая задача), тогда действительно разница будет заметна в меньшей степени (т.к. ваша задача уже не про запросы, а про тяжёлый парсинг), но она всё равно будет на стороне асинхронного подхода (синхронно вы не сможете утилизировать 100% CPU без переключений контекста, т.к. в задаче всё ещё присутствует IO).

Другой вопрос в том, когда вам это действительно нужно. В большинстве случаев вам дешевле докупить CPU. У меня лично есть задачи, которые в синхронном режиме принципиально не решаются на подходящем мне уровне отзывчивости сервиса.

PS: Вы зря поменяли мою задачу. Решите её. Сравните. Распространите на все имеющиеся у вас потоки IO. Пока ощущение, что вы не до конца понимаете преимущество асинхронного IO. Моя задача как раз про обучению преимуществам работы с асинхронным IO. Здесь нет разницы — делаете вы http-запросы, отправляете SQL-запросы в базу, делаете какой-то свой TCP-сервер, отправляете или читаете сообщения из очереди, оперируете тонными данных из Cassandra — все эти операции завязаны на IO: исходная задача как раз про много параллельных IO-потоков, какие именно данные у вас ходят внутри стримов — не имеет значения для eventloop.

AloneCoder файберы не могли появиться в декабре 2020 года в PHP 8.1, т.к. эта версия пхп ожидается лишь в конце 2021 года. Пока только принят RFC, нужно ещё чтобы расширение приняли в апстрим. Но я надеюсь тут накладок не будет, что они действительно появятся и к концу года вместе с этим выйдет amphp3. Было бы замечательно.


И обнови сертификат на своём сайте. Он почти три месяца как протух )

на идеях автора, что вот мол мы однажды возьмем и выкинем nginx ставят крест вовсе не возможности php, а его производительность и чрезмерное усложнение разработки.
standalone php сервер еще много лет будет оправдан для как максимум для быстрых api запросов с минимальной ветвистостью логики. но все это в любом случае будет за каким-нибудь nginx, из которого будет попадать по http/1.1 или даже http/1.0, потому что производительность при разборе http2 пакетов уже очень сильно деградирует и это дело компилируемых языков, с http3 скорей всего дела будут еще хуже.

для примера сравните утилизацию CPU amphp/http и curl, например.
даже в php8 с jit, даже с nghttp для разбора http2.

PHP с каждой версией все больше усложняется.
В своё время многие начинали осваивать разработку с него из-за низкого порога входа. Написал echo 123 и вот результат твоих трудов в интернете.

Я думаю Go занял это место.

Большинство задач предпочту решать с помощью Go из-за его простоты, конкурентности и параллелизма, лаконичности и предсказуемости. Известно как работает Go под капотом.

С современным же PHP ситуация обратная. Куча библиотек во фремворках, синтаксический сахар и магия. Каша в стандартных функциях тащится из версии в версию. Всё это повышает энтропию кода, с языком просто не комфортно работать.
В этом плане подход Kotlin мне больше нравится. PHP стоит взять его за пример, если они хотят наращивать функционал языка.
Он не усложняется, а расширяется. Вы всё так же можете писать код с echo и глобальными переменными, без типизации, классов и этого Fiber.
Вот про кривые и недоделанные костыли, которыми он расширяется, вы действительно правы. Ту же типизацию завозили частями в минорных и даже мажорных версиях, а в итоге коллекции до сих пор приходится подпирать через phpdoc.
UFO just landed and posted this here
Такая реализация с yield уже есть в recoilphp и amphp. Но это костыль, который как минимум портит возвращаемые типы. Fiber, по своей сути, — ещё более умный генератор.
Sign up to leave a comment.