Здравствуйте, so5team, Вы писали:
F>>2. отказоустойчивость в случае ошибок (система не должна зависать и падать в принципе)
(и все же философия эрланга — все падает, deal with it)
S>Загляните, пожалуйста, в исходники Erlang/OTP, в функцию erts_alc_fatal_error в частности. И объясните, как это ваше требование выполняется в Erlang-е, где невозможность аллокации памяти приводит к завершению работы всей VM.
Так а что еще делать, если память кончилась?
А на практике, если вы не забыли про erlang:system_monitor а vm упала с out of memory, 99% что утечки в c++ (ниф или драйвере), и не совсем честно считать это проблемой эрланга.
Здравствуйте, vdimas, Вы писали:
V>Речь про UDP-сокет.
Ну, то есть это подходит только к особенным задачам, когда мы владеем и клиентом и сервером и имеем свободу выбора протокола. Тогда да — можно навелосипедить свой IOCP без IOCP.
Это как бы не решит нашу исходную проблему, зато позволит похвастаться самопальным аналогом IOCP.
V>IAX — это порождение Linux, на нем нет IOCP, но есть вот такие трюки. И есть еще целый набор "фиктивных" файлов, типа eventfd, на которых можно организовать похожую схему.
Непонятно, что делать с нефиктивными файлами.
V>Просто напомню, что IOCP — это не только ввод/вывод, это просто механизм очереди событий, некий "порт", к которому можно подключить и ввод-вывод в том числе, и тогда PostQueuedCompletionStatus будет выполнять сама система по готовности данных.
IOCP, в данном контексте, это механизм, который позволяет нам "ждать" неограниченного, в принципе, количества событий, не потребляя на каждое из них системный thread.
Напомню, что исходная проблема — ровно в том, что традиционные императивные ЯП ориентированы именно на концепцию "control flow", и весь ввод-вывод предполагается блокирующим.
Готовых механизмов для того, чтобы "уснуть" в точке вызова, и "проснуться" в момент прихода события, и при этом не занимать thread, в них нету.
Вот про это я и спрашивал. А про то, как организовать IOCP для веб-сервера, если у нас нету IOCP — это другой вопрос, на мой вкус малоинтересный. Особенно если ответ на него предполагает замену клиентских браузеров на клиентов протокола AIX.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, so5team, Вы писали:
F>>2. отказоустойчивость в случае ошибок (система не должна зависать и падать в принципе) S>Загляните, пожалуйста, в исходники Erlang/OTP, в функцию erts_alc_fatal_error в частности. И объясните, как это ваше требование выполняется в Erlang-е, где невозможность аллокации памяти приводит к завершению работы всей VM.
Здравствуйте, meadow_meal, Вы писали:
F>>>2. отказоустойчивость в случае ошибок (система не должна зависать и падать в принципе)
_>(и все же философия эрланга — все падает, deal with it)
Этот пункт был специально обозначен neFormal-у дабы показать, что некорректно предъявлять такое требование к конкурентам Erlang-а, если сам Erlang не в состоянии его выполнить. Причем как раз за счет одного из основных принципов -- let it crash, который воплощен в жизнь не только для легковесных потоков, но и для самой Erlang-овой VM.
Так что пункт "система не должна зависать и падать в принципе" не относится к Erlang-у в принципе.
S>>Загляните, пожалуйста, в исходники Erlang/OTP, в функцию erts_alc_fatal_error в частности. И объясните, как это ваше требование выполняется в Erlang-е, где невозможность аллокации памяти приводит к завершению работы всей VM.
_>Так а что еще делать, если память кончилась?
Если аллокация была инициирована из Erlang-ового кода, то можно бросить исключение.
Если из нативной NIF-ки, то почему бы не вернуть из nif_alloc_resource NULL вместо аборта всей VM.
Допустим, приходит (N+1) клиент, дергается реализованная в NIF-е функция, там вызывается nif_alloc_resource и оказывается, что очередные 128 байт для этого клиента выделить не удается. Вместо того, чтобы вернуть NULL из nif_alloc_resource и какой-нибудь тупл {err,code} из NIF-функции, дабы потом в Erlang-овом коде просто убить созданный для (N+1) клиента процесс, грохают всю VM.
_>А на практике, если вы не забыли про erlang:system_monitor а vm упала с out of memory,
На практике Erlang хорошо тормозит и падает даже у тех, кто знает про system_monitor.
_> 99% что утечки в c++ (ниф или драйвере), и не совсем честно считать это проблемой эрланга.
Собственно, об этом и было сказано по ветке выше: как только из-за родных тормозов Erlang-а в приложении оказывается достаточное количество кода, достоинства Erlang-а испаряются и Erlang превращается в такой же клеевой динамически-типизированный язык, как Python/Ruby/Lua и еще куча других.
Но там же было сказано и более важное: нельзя предъявлять к C++/Scala/C#/Haskell/Ada и пр. такую претензию, что в этих языках нет фишек Erlang-а. Конечно их там нет. Более того, очевидно, что их там и не может быть (особенно если язык нативный). Но для решения таких же проблем concurrency computing и distributed computing в этих языках просто-напросто будут использоваться другие подходы и другие инструменты. И результат будет получаться не менее достойный.
Так что, если кого-то устраивает Erlang, то почему просто не использовать его и не делится success stories? Отличный язык, отличная VM, отличные библиотеки для него.
Только не всем подходят. А у тех, для кого Erlang не подходит, есть другие языки и другие инструменты.
Здравствуйте, neFormal, Вы писали:
I>>Да, нужно навроде драйвера. Сам драйвер так же вводит издержки, вроде пенальти на времени отклика и тд.
F>если там и так задержки, то не пофиг ли уже?
Смотря как это будет проявляться. Если на 100мс задержкится респонс, то нормально. А если на 100мс замедлится обработка тех же мышиных сообщений в динамичной игре, то это уже фатально.
Здравствуйте, neFormal, Вы писали:
F>>>2. отказоустойчивость в случае ошибок (система не должна зависать и падать в принципе) S>>Загляните, пожалуйста, в исходники Erlang/OTP, в функцию erts_alc_fatal_error в частности. И объясните, как это ваше требование выполняется в Erlang-е, где невозможность аллокации памяти приводит к завершению работы всей VM.
F>через соседнюю железку?
Да, а это значит, что partition tolerance искаропки, а выбирать придется между consistency и availability. Смешно — если выбрать consistency, то хваленый реалтайм эрланга перестанет давать какие либо гарантии на время отклика.
Здравствуйте, Mamut, Вы писали:
S>>Неужто у эрланга все так плохо? Чего-то не верится...
M>Тут сейчас тебе Wolfhound начнет нести свою любимую чушь про языки, ты его не слушай. У нас все его ходы записаны, они уже много лет не меняются.
Самое интересное, что у тебя аргументы лет 10 не меняются: "чушь!", "неверно!", "матчасть!", "куридопосинения!"
Лет десять назад это было даже забавно. Похоже, в какой то момент вы с Шериданом поменялись аккаунтами.
Здравствуйте, Шеридан, то есть, Mamut, Вы писали:
M>Есть некоторые задачи, которые плохо ложатся на ФП. Это не проблема Эрланга, как такового. Ну 90% проектов у тебя не будет просто банально потому, что в 2015-м году вершиной мысли в большинстве языков является аналоги WaitForThread и mutex.lock(), а однопоточная VM называется web-scale
Догадываюсь, откуда твоя боль. "однопоточная VM" — это ты скорее всего про Node.js. Ты наверное попутал Node.js с абстрактным джаваскриптом.
Node.js как VM никогда, ни разу не был однопоточной VM. И это несмотря на то, что js в ноде однопоточный. Парадокс ? Как то так
"вершиной мысли в большинстве языков" — смешно. Джава, дотнет, питон уже давно отказались от этой вершины мысли. С, С++ — вобщем, в процессе.
Здравствуйте, so5team, Вы писали:
S>Допустим, приходит (N+1) клиент, дергается реализованная в NIF-е функция, там вызывается nif_alloc_resource и оказывается, что очередные 128 байт для этого клиента выделить не удается. Вместо того, чтобы вернуть NULL из nif_alloc_resource и какой-нибудь тупл {err,code} из NIF-функции, дабы потом в Erlang-овом коде просто убить созданный для (N+1) клиента процесс, грохают всю VM.
Возможно, мне сложно выйти за рамки собственного опыта, но я не вижу смысла в этом искусственном жизнеобеспечении. Проблему надо решать значительно раньше — через лимиты и балансировку нагрузки, а не ждать пока VM сожрет весь своп и начнет непредсказуемо срубать приложение по частям (при описанном выше предложении).
Решение завершать работу виртуальной машины — осознанное, а не потому что по другому не смогли.
_>>А на практике, если вы не забыли про erlang:system_monitor а vm упала с out of memory,
S>На практике Erlang хорошо тормозит и падает даже у тех, кто знает про system_monitor.
Во-первых, в описанном случае как помогло бы не срубать vm при out of memory? Отложило бы падение еще на секунду?
Во-вторых, system_monitor и лимиты (на число запросов в одной сессии — см. комментарии) в этом случае должны были помочь (но их не было), так что падение можно было предотвратить. Да, клиент бы свой плейлист не получил, но и только.
S>Собственно, об этом и было сказано по ветке выше: как только из-за родных тормозов Erlang-а в приложении оказывается достаточное количество кода, достоинства Erlang-а испаряются и Erlang превращается в такой же клеевой динамически-типизированный язык, как Python/Ruby/Lua и еще куча других.
Спору нет, Эрланг язык нишевый, но ниша эта широка. Нативный код — это математика, обработка текста, большие мутабельные массивы данных, интеграция с нативным api. Для кого-то это много, для кого-то небольшой процент от задачи. Использовать Эрланг как клеевый язык смысла, конечно, нет. (Я не спорю — соглашаюсь).
S>Так что, если кого-то устраивает Erlang, то почему просто не использовать его и не делится success stories?
Мы пишем игровые сервера на Эрланге, приходилось интегрировать bullet3d (порядка 500 динамических миров на сервер, шедулер справляется), box2d, самописные тайловые и воксельные движки, но это 5-10% задач, большая часть времени все равно уходит на игровую логику, так что достоинствами Эрланга наслаждаемся в полный рост. (Под достоинствами Эрланга я имею в виду скорее архитектурную модель и волшебную вм, сам язык слишком уж консервативен, но иммутабельность и возможности метапрограммирования — две особенно важные для нас фичи, которые позволяют с этим мириться).
, производительностью, фундаментально неущербной многопоточностью? Ой да, я забыл. Кроме пафоса и апломба нет ничего. Уже лет пять-семь как. WH>Лучший в мире генератор парсеров уже есть.
Опять "лучший" и уже наверное третий год обещаний "скоро мы сделаем тааакоое !"
Здравствуйте, Ikemefula, Вы писали:
I>Смотря как это будет проявляться. Если на 100мс задержкится респонс, то нормально. А если на 100мс замедлится обработка тех же мышиных сообщений в динамичной игре, то это уже фатально.
делать динамичную игру на таком медленном языке — это уже фатально.
Здравствуйте, so5team, Вы писали:
S>Этот пункт был специально обозначен neFormal-у дабы показать, что некорректно предъявлять такое требование к конкурентам Erlang-а, если сам Erlang не в состоянии его выполнить.
всегда можно найти какую-то зацепку. но плюсам от этого не легче.
кстати, что с остальными пунктами?
Здравствуйте, meadow_meal, Вы писали:
_>Мы пишем игровые сервера на Эрланге, приходилось интегрировать bullet3d (порядка 500 динамических миров на сервер, шедулер справляется), box2d, самописные тайловые и воксельные движки, но это 5-10% задач, большая часть времени все равно уходит на игровую логику, так что достоинствами Эрланга наслаждаемся в полный рост.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>2. Я в код не смотрел, но разве boost::future::then создаёт новый поток с блокирующим wait/get, вместо того чтобы просто прицепить продолжение к текущему future? V>>Да, потому что у текущего future<> некуда цеплять продолжение.
EP>Я вижу внутри вектор под продолжения: EP>https://github.com/boostorg/thread/blob/master/include/boost/thread/future.hpp#L137 EP>
Необходимо цеплять как продолжение не future, а код, который порождает future, т.е. необходимо цеплять обычные колбэки/лямбды, чтобы не было столь мучительно стыдно за приведенные отрывки.
Да и вообще, реализация future из boost, даже не беря continuations — какая-то детсадовская, сорри. Мьютекс, condition variable, отложенный колбэк самому себе, наличие которого проверяет каждый раз при захвате мьютекса, брррр... индусокод во всей красе (хотя, не уверен, что это индусы писали... студенты какие-нить). Для future::shared_state ничего подобного не надо и близко, замечательно всё разруливается на легковесно на lock-free, в т.ч. continuations.
========
Я рядом давал кучу ссылок уже на proposals.
Герб Саттер и Ко предлагают добавить в C++17 аналогичные механизмы. Причем, прямо на достижения из жабаскрипта и ссылаются, куда я ссылки дал.
C++ suffers an evident deficit of asynchronous operations compared to other languages, thereby hindering programmer productivity. JavaScript on Windows 8 has promises (then, join and any), .NET has the Task Parallel Library (ContinueWith, WhenAll, WhenAny), C#/VB has the await keyword (asynchronous continuations), and F# has asynchronous workflows. When compared to these languages, C++ is less productive for writing I/Ointensive applications and system software. In particular writing highly scalable services becomes significantly more difficult.
This proposal introduces the following key asynchronous operations to std::future, std::shared_future, and
std::async, which will enhance and enrich these libraries.
then:
In asynchronous programming, it is very common for one asynchronous operation, on completion, to invoke a
second operation and pass data to it. The current C++ standard does not allow one to register a continuation to
a future. With then, instead of waiting for the result, a continuation is “attached” to the asynchronous
operation, which is invoked when the result is ready. Continuations registered using the then function will help
to avoid blocking waits or wasting threads on polling, greatly improving the responsiveness and scalability of an
application.
Но прототип из буста, вместо запуска продолжения из потока, в котором future становится resolved или failed, тупо запускает новый поток, в котором уже вызывает первое продолжение из списка, а затем в БЛОКИРУЮЩЕМ режиме просто ожидает готовность этого следующего future, которое, в свою очередь, тоже запустит новый поток для следующего then и так далее по цепочке. Дичь же, согласись! ))
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>В ASIO есть поддержка IOCP, если чего-то необходимого нет — то при необходимости реализуется. EP>Вопрос же скорее был про неявную нарезку алгоритма на фрагменты ("same fringe problem") — вот для этого подходит Boost.Coroutine, причём не только для IOCP — а и для любого другого подобного асинхронного кода.
Ну, stateful нечестно ))
Для которотких и "неглубоких" обработчиков он, прямо скажем, из пушки по воробьям.
Вот у тебя 200k сессий съели почти всю память под стеки, а в случае stateless нужно ровно столько стеков, сколько физических потоков в пуле. При том, что "коротких" stateless-обработчиков может быть хоть под миллион и они нифига не съедят столько памяти.
Здравствуйте, meadow_meal, Вы писали:
_>Возможно, мне сложно выйти за рамки собственного опыта, но я не вижу смысла в этом искусственном жизнеобеспечении. Проблему надо решать значительно раньше — через лимиты и балансировку нагрузки, а не ждать пока VM сожрет весь своп и начнет непредсказуемо срубать приложение по частям (при описанном выше предложении).
Боюсь, вы уводите разговор в другую сторону. Некто под ником neFormal выдвинул ряд требований к языкам/фреймворкам/платформам, которые должны быть выполнены прежде, чем эти языки/фреймворки/платформы смогут считаться достойными сравнения с Erlang-ом. При этом в списке требований был пункт про отсутствие зависаний и крахов в принципе.
Несложно показать, что в принципе, сам Erlang не спасает ни от зависаний, ни от крахов.
Однако, если это показать, то затем начинаются разговоры о том, что "зачем же так делать", "есть же мониторы, лимиты, горячий резерв" и пр. Только все эти рассуждения перемещают нас в другую плоскость: проблем не будет, если все сделать по уму. Т.е. внезапно выясняется, что волшебства никакого нет, нужно по-уму. Спрашивается, почему по-уму нельзя сделать на C++, Scala или Haskell? А так же, если по-уму можно сделать в Erlang, то почему не делают и примеры для этого не нужно долго искать.
Так что одно из требований neFormal-а просто не выполняется для самого Erlang-а. Не более и не менее того.
Здравствуйте, neFormal, Вы писали:
F>так много слов а суть проста. другим технологиям необходимо добиться паритета по следующим пунктам: F>1. параллельное выполнение множества задач
Параллельное выполнение множества задач поддерживается в многозадачных ОС уже лет 50 как, если не больше. А с момента появления и распространения ОС, в которых единицей диспетчеризации является не процесс, а нить, прошло уже лет 25-30.
Т.о. зачем перекладывать на VM задачи, которые уже решены на уровне ОС, не понятно в принципе.
Тем более, что от общей проблемы (обеспечение продвижения вперед для M параллельных вычислений всего на N вычислительных ядер) Erlang-овская VM спасает не более, чем обычный пул потоков.
F>3. единое пространство потоков/процессов на нескольких физических юнитах
Честно скажу, не очень понимаю, что это такое и зачем это нужно. Полагаю, что хороший пример чего-то подобного можно увидеть в .NET-овском Orleans, который уже упоминался выше в связи с очень интересной моделью акторов.
_>Возможно, мне сложно выйти за рамки собственного опыта, но я не вижу смысла в этом искусственном жизнеобеспечении. Проблему надо решать значительно раньше — через лимиты и балансировку нагрузки, а не ждать пока VM сожрет весь своп и начнет непредсказуемо срубать приложение по частям (при описанном выше предложении).
Для того, чтобы словить bad_alloc не обязательно сжирать всю память и лезть в своп, можно просто попросить у системы очень много памяти одним куском, запрос не сможет быть удовлетворен и malloc вернет null. Эту ошибку вполне можно обработать.