Node.JS complexity rant

Oct 14, 2011 17:42

Создатели целой социальной сети на основе Node.JS подтверждают всё то, что эрлангисты сразу говорили: Node.JS ск сложный и лапшистый:

Цитируя лозунг создателей NodeJS ( Read more... )

erlang

Leave a comment

ex_juan_gan October 15 2011, 02:26:48 UTC
А, так у них cps вместо синхронизации! Люблю, теоретически. Я б побаловался, чисто опыта набрать.

Но ведь эрланг тоже примерно так устроен, нет?

Reply

lionet October 15 2011, 06:40:41 UTC
Нет. В эрланге ты программируешь линейно. Сделал A, затем сделал B. В Node.JS ты программируешь через коллбеки: сделал A, которому скормил коллбек, который позовёт B. Это лапша.

Reply

sheremetyev October 15 2011, 19:18:30 UTC
По-моему, коллбеки или линейный код - вопрос синтаксиса. Если хочется, то можно коллбеки автоматически разворачивать.

Reply

lionet October 15 2011, 21:53:31 UTC
1. Конечно, вопрос синтаксиса. И это важно чрезвычайно. Именно из-за синтаксиса мы не программируем на брейнфаке, а хотим более высокоуровневых и, одновременно, простых конструкций.

2. Кафеин не скрывает сложность модели выполнения Node.JS: всё равно нужно помнить, где восклицательные знаки расставлять. А если вдруг забыл - то всё заблокируется напрочь. Нельзя пропустить _ни одного_ восклицательного знака. Во всех тысячах строчек кода. Иначе именно этот пропущенный знак когда-нибудь выстрелит.

Reply

sheremetyev October 16 2011, 09:02:58 UTC
Не очень понял насчет заблокируется. Если пропустить восклицательный знак, то код после асинхронного вызова будет выполнен сразу же, а не "потом". А "потом" (после завершения асинхронной операции) не будет выполнено ничего. Например, если в первом примере по ссылке пропустить восклицательный знак, то append() будет вызван с неопределенным параметром.

Reply

lionet October 16 2011, 12:10:50 UTC
Речь не только про append. Но и про остальные тыщи API-операций, часть которых лишь часть действительно асинхронна.

Я действительно допустил небрежность в объяснении. Не только восклицательные знаки нужно расставлять, но и избегать синхронных вызовов надо. То есть, ни одна функция, теоретически, не может быть безопасной для соседних потоков. Частью эта проблема решается соглашением о наименовании. Фольклором! А не особенностями VM, которые принципиально не допускают блокировки.

Кроме того, даже использование асинхронных функций сопряжено с граблями!

Например, потерянный коллбек блокировки даст неопределённый порядок применения операций:

node.fs.rename("/tmp/hello", "/tmp/world");
node.fs.stat("/tmp/world", function (status, stats) { ... });Вот здесь stat может выполниться раньше, чем завершится операция rename ( ... )

Reply

sheremetyev October 16 2011, 15:21:37 UTC
Насколько я знаю, синхронные в Node только штук 30 функций для файлового ввода-вывода. Это аналоги соответствующих асинхронных функций, добавленные "для удобства". Пользоваться ими категорически не рекомендуется по понятным причинам. Я считаю их вообще зря добавили и со временем уберут.

Кроме этих функций блокироваться практически больше нечему, если самому вечный цикл не написать. Никакого sleep(), например, нету. Поэтому, как правило, если процессор чем-нибудь занят то он занят полезной работой, а не читает тупо один и тот же адрес в памяти ради синхронизации потоков. Думаю, именно это имеется ввиду когда говорят "because nothing blocks".

Reply

tretiy3 October 16 2011, 19:08:44 UTC
я не специалист по node.js, но писал, маленько, на twisted.
штука в том, что каждая пользовательская функция/метод синхронна по умолчанию.
в смысле: файл-то он прочитает ассинхронно, но нужно, ведь, не только прочитать, но и распарсить, к примеру. а в такие штуки ассинхронность приходится руками засовывать. в какой-то момент говорить: "стоп - пускай теперь другие поработают". завернуть в колбек не сложно. в питоне для cps есть yield. (говорят в какой-то реализации яваскрипта тоже есть). для обработки ошибок нужно вместе с каждым колбеком вешать errback. и если грамотно составлять эти цепочки, то в целом, жить можно.
только очень сложно дебажить такую монструозную штуку на генераторах. где-то забыл поставить errback и хрен разберешься где падает.

Reply

ko_bx October 16 2011, 22:19:32 UTC
Странно как-то это, путать асинхронность ввода/вывода с параллельностью просчетов разных.

Для асинхронности ввода/вывода всем хорош gevent -- пропатч сокеты/потоки/работу с файлами, создавай на каждый "обработчик" по зелёному потоку и всё тут, дальше пиши код в синхронном стиле, а тот сам будет засыпать/просыпаться и так далее.

ну а обработка файлов и прочие операции подобные -- здесь уже пул процессов-воркеров какой-то нужен, а если совсем много -- сделать через celery какой-нибудь. такое себе разделение труда. а кому нужно -- пусть слушает/ждёт завершения определенных задач.

а вы всё это на twisted в один поток делали? (вместе с парсингом и проч.) или я неправильно понял?

Reply

tretiy3 October 17 2011, 06:24:42 UTC
неточно выразился про ассинхронность.
конечно речь о block/non block коде.
под ассинхронной функцией понимается функция, которая не делает сразу всю свою работу и возвращает управление вызвавшей ее функции как можно быстрее.
Да в один поток, конечно.
И в ноде все в один поток делается.

Reply

ex_juan_gan October 15 2011, 20:40:33 UTC
Ну вот; рассеиваются иллюзии. А как же многопоточность в Эрланге поддерживается? Разве не через акторов?

Reply

lionet October 15 2011, 21:51:31 UTC
Многопоточность - это штучки-дрючки VM. В эрланге как языке стиль программирования линейный.
V = http:call(),
Z = ldap:call(V),
http:call(Z).

Reply

ex_juan_gan October 16 2011, 01:51:01 UTC
Понятно; как и в джаваскрипте - и вопросов не возникает.

Reply

lionet October 16 2011, 02:13:12 UTC
В чистом Node.JS так нельзя писать - заблокируется всё нафиг на первом же колле. Надо коллбеки плодить.

Reply

ghostwheel October 16 2011, 08:40:15 UTC
дурацкий вопрос: Node.JS создали, чтобы было трудно, но задорно?

Reply

lionet October 16 2011, 08:43:24 UTC
Если почитаешь то, что написал создатель Node.JS - то да, примерно так и получается. У него не было знаний и опыта разных подходов к проектированию 24/7 сервисов, поэтому и получилось так.

К сожалению, это надолго.

Reply


Leave a comment

Up