Я рад объявить о выходе новой стабильной версии Node.
Переход на неё приносит значительные улучшения во многих областях, сосредоточенные на улучшении API, на простоте употребления, на обратной совместимости.
Весьма краткий обзор значимых изменений API по сравнению с v0.8 читайте, пожалуйста, на странице вики об изменениях API.
Streams2
В предыдущей блогозаписи мы представили вам изменения API, названные «Streams2». Если вы не успели осмотреть их, прочтите, пожалуйста, теперь хотя бы тогдашний подраздел «tl;dr».
Изменения интерфейса потоков подготавливались давно. С самых ранних дней Node всем нам было вроде как известно, что «события data начинают сразу поступать» и «вызов pause() не обязательно оказывает эффект» — это страшная и ненужная фигня. В версии 0.10 мы наконец поднапряглись и устроили коренные изменения, улучшившие поведение потоков.
Что ещё важнее, теперь все потоки в ядре Node устроены на основе одного и того же набора легко расширяемых основных классов, так что поведение их стало гораздо предсказуемее, а также небывало упростилось создание потоковых интерфейсов для ваших собственных пользовательских программ.
По правде говоря, API Streams2 разрабатывался по мере использования его для модулей из реестра npm. В настоящий момент 37 опубликованных модулей Node ужé пользуются библиотекою readable-stream в качестве одной из своих зависимостей. Пакет readable-stream для npm позволяет использовать новую форму интерфейса Stream в вашем прежнем коде v0.8.
Домены ошибок и обработка ошибок
Статус модуля domain повышен с «экспериментального» до «нестабильного». Внутренне модуль подвергся дополнительной первоклассной переработке, что упростит его использование в ряде граничных случаев, наблюдавшихся при употреблении этого модуля для обработки ошибок поверх версии v0.8. В частности, домéнная обработка ошибок более не полагается на обработчик process.on('uncaughtException'), и код C++ в Node теперь осведомлён о доменах.
Если ранее вы не использовали доменную ловлю ошибок в своих программах, но иногда желали бы получать улучшенную отладочную информацию о выбрасываемых ошибках (особенно посередь множества запросов и асинхронных вызовов), то тогда вам непременно следует попробовать этот модуль.
Ускорение process.nextTick
В версии 0.8 (да и ранее) функция process.nextTick() размещала переданную ей функцию обратного вызова (callback) в очереди событий. Это обычно приводило к запуску callback прежде, чем начинались операции ввода-вывода. Однако же такое поведение не гарантировалося.
В результате во множестве программ (да и в некоторых частях движка Node) началось употребление process.nextTick в качестве интерфейса «сделать это попозже — но раньше, чем начнётся реальный ввод-вывод». И так как обычно всё так и случалось, то такой подход казался годным.
Однако под нагрузкой была возможною постановка сервером в очередь такого множества операций ввода-вывода, что переданные через nextTick вызовы оттеснялись. И это приводило к нелепым ошибкам, вызывало состояние гонки — а исправить это было никак нельзя, если только не переменить саму семантику nextTick.
Так что именно так мы и сделали. В версии 0.10 обработчики nextTick срабатывают сразу после каждого вызова, из C++ в JavaScript происходящего. И это означает, что если у вас в джаваскриптовом коде вызывается process.nextTick
, то переданная функция обратного вызова (callback) запустится сразу после отработки основного кода — прежде того момента, когда начнётся обработка очереди событий. Гонка окончена. Всё хорошо.
Однако были на свете и такие программы, которые употребляли рекурсивный вызов process.nextTick именно для откладывания очередного шага долгосрочных низкоприоритетных задач до того момента, когда отработает очередь событий ввода-вывода. Чтобы ничего не поломалось, движок Node теперь станет печатать предупреждение о такой ситуации и просить вас о переходе на новую функцию setImmediate для таких вызовов.
Время отклика и сборка мусора в свободное время
В языках, полагающихся на сборку мусора, её бывает далеко не просто настроить правильно. Чтобы избежать излишнего использования памяти, ранее движок Node пытался указывать движку V8 на необходимость сбора мусора всякий раз, когда очередь событий опустевала.
К сожалению, весьма сложно знать в точности, когда такая необходимость возникает. «Свободное время» может быть не очень-то свободным, и если ошибиться, то можно потратить кучу времени на сбор мусора в самый неожиданный момент. На практике выяснилось, что отключение вызова IdleNotification приводит к улучшению производительности, но не к излишнему использованию памяти, потому что движок V8 и сам неплохо знает, когда лучше запустить сбор мусора.
Так что в версии 0.10 мы этот вызов выковыряли. (Есть и такая точка зрения, что мы избавились от бага, каковым было само употребление этого вызова с самого начала.) В результате время отклика сделалось предсказуемее и стабильнее. Разницы в бенчмарках вы в результате не заметите, однако, вероятно, обнаружите, что времена отклика вашего приложения сделалися понадёжнее.
Производительность и бенчмарки
Примечание переводчика: на Хабрахабре, насколько мне известно, вообще нет сколько-нибудь сносных средств для изменения фона во блоках текста, записанного одноширинным шрифтом. Поэтому от перевода этого подраздела с грудами цифр я воздержусь — читайте его в первоисточнике, кому необходимо. Суть же его в том, что производительность движка Node возросла в целом ряде его возможных приложений, но в некоторых и поуменьшилась (например, чуть медленнее посылаются буферы и строки UTF-8 через сеть).
Непрерывная интеграция
Для поддержания высокого уровня стабильности кода (и чтобы можно было надеяться на более раннее отлавливание ошибок) у нас используется Jenkins, прогоняющий каждый коммит через набор тестов на каждой из поддерживаемых операционных систем. Наблюдать за этим вы можете на веб-портале Node Jenkins.
Вскорости у нас начнётся ежедневная автогенерация еженощных сборок (nightly builds), а со временем и весь процесс выпуска новых версий Node будет автоматизирован.
Хотя разработчики довольно скрупулёзно пользовались тестами и бенчмарками, при ручном и частном подходе некоторые недочёты могли быть обойдены вниманием. Общее автоматическое тестирование продукта позволит предотвращать ухудшения продукта, подобные тому, из-за которого выпуск 0.10 задержался на несколько месяцев.
Внешнее развитие
Год назад мы объявили, что инновации в мире Node станут происходить в области пользовательских модулей. Теперь мы воплотили это мнение в его логически завершённой форме, разрабатывая новые версии внутренних модулей Node в качестве пользовательских. Появление модулей readable-stream и tlsnappy в такой форме позволило им получить больше пользовательского тестирования, экспериментов, пожертвований кода.
Такой модуль может использоваться как слой совместимости, позволяющий библиотекам прибегать к новым возможностям Node даже при необходимости поддержки старых версий движка Node. Этот путь развития внутренних модулей Node необыкновенно эффективен. В дальнейшем развитие будущих разработок в форме пользовательских модулей продолжится.
Взросление
Нередко с интересом спрашивают, готов ли движок Node для настоящего дела. Обычно я отвечаю, что это зависит от требований, предъявляемых вашим настоящим делом, а на Node работают многие высоконагруженные сайты, и возможности «реальных» компаний, использующих Node в Бизнесе, возросли больше, чем когда-либо прежде.
Тут места не хватит привести полный список компаний, использующих Node, и полный перечень вариантов поддержки и обучения. Однако вот несколько вариантов, быстро расширяющихся и заполняющих пространство «Node для предприятий».
Ищущим коммерческой поддержки пригодится StrongLoop (компания Бена Noordhuis и Берта Белдера), выпустившая дистрибутив, содержащий Node v0.10, которому они станут оказывать поддержку на Windows, на Маках, на Red Hat/Fedora, на Debian/Ubuntu и на множестве облачных платформ. Скачать их дистрибутив Node вы можете вон там.
The Node Firm — всемирная организация ключевых авторов кода Node и членов сообщества, оказывающая помощь предприятиям в успешном употреблении Node. Они оказывают услуги тренировки персонала, консультации, архитектурные наставления, оформляют подписку на консультации, что помогло Skype, Qualcomm и другим клиентам быстро и эффективно освоить Node.
Node в его нынешнем виде немыслим без npm, а npm — без его реестра опубликованных модулей. Однако для многих коммерческих предприятий проблематично полагаться на общественный реестр. Iris npm предлагает полностью управляемый частный npm-реестр от Iris Couch — команды, отвечающей за работоспособность общественного npm-реестра.
Joyent — компания, вероятно известная вам как хранитель проекта Node — обеспечивает высокопроизводительную облачную инфраструктуру, специализируясь на приложениях реального времени в сайтостроении и для мобильных устройств. Joyent широко использует Node в своих инженерных решениях, а также предлагает впечатляющие средства отладки приложений после сбоев и анализа производительности в реальном времени для приложений на Node.js. Joyent — также и мой работодатель, так что мне пришлось бы искать «реальную» работу, не будь они спонсорами Node :)
Что дальше: v0.12
Развитие Node v0.12 будет сосредоточено на улучшении HTTP. Нынешняя реализация HTTP в Node весьма неплоха, и её вполне хватает для множества небезынтересных приложений. Однако:
- Исходный код чрезмерно запутан. Множество кода одновременно используется в сервере и клиенте, но таким образом, что пренеприятно даже читать его, не говоря уж об исправлении ошибок. Произойдёт разделение кода сервера и клиента, более ясными сделаются их интерфейсы.
- Поведение опросчика сокетов является озадачивающим и противоестественным. Мы сделаем его конфигурируемым и вынесем в отдельную утилиту. Что позволит сделать более разумным поведение KeepAlive, а также сделает все эти элементы пригодными для употребления и в ваших собственных программах.
Ведутся эксперименты над модулем tlsnappy, который в дальнейшем может стать внутренней реализацией TLS и заметно ускорить это дело.
1.0
После 0.12 следующей крупной стабильной версией станет 1.0. В тот момент не многое переменится в ежедневной работе проекта, однако эта версия станет важною вехою стабильности и сокращения готовности ко внедрению новых фич. Однако же и без того мы строго стремимся к обратной совместимости, так что и в этом изменение не окажется сильным.
Новые версии, впрочем, продолжат выходить, особенно по мере выхода новых версий тех компонентов, на которых Node основан, и будут исправляться баги. Обсуждалась привязка циклов выпуска Node к V8 и некоторые небезынтересные возможности автоматизации процесса выхода новых версий.
Целью Node всегда было достижение со временем «окончательного» состояния основной программы. Конечно, планка эта — изрядно возвышенная, а не то и недосягаемая. Но по мере широкого внедрения Node и роста разнообразия применений Node мы всё ближе к тому дню, когда значимые инновации станут происходить за пределами основной программы Node.
Стабильность платформы обеспечивает развитие поверх неё.
А теперь — традиционный отчёт о выпуске:
11 марта 2013 года, версия 0.10.0 (стабильная)
- npm: апгрейд до версии 1.2.14
- core: правильно дополнять имя файла в dlopen под Windows (isaacs)
- zlib: корректно обрабатывать флаги опустошения (isaacs)
- domains: обрабатывать ошибки, выброшенные во вложенных обработчиках ошибок (isaacs)
- buffer: очищать старшие биты при преобразовании в ASCII (Ben Noordhuis)
- win/msi: разблокировать модификацию и восстановление (Bert Belder)
- win/msi: некоторые части Node сделать выбираемыми (Bert Belder)
- win/msi: постоянство путей ко ключам в реестре (Bert Belder)
- child_process: поддерживать отсылку dgram socket (Andreas Madsen)
- fs: будет возникать ошибка EISDIR в Windows при применении fs.read/write к каталогу (isaacs)
- unix: устранить строгие предупреждения о псевдонимности, макрофицировать функции (Ben Noordhuis)
- unix: уважить переменную окружения UV_THREADPOOL_SIZE (Ben Noordhuis)
- win/tty: исправить опечатку в перечислении атрибутов цвета (Bert Belder)
- win/tty: не трогать режим вставки или быстрого редактирования (Bert Belder)
Автор: Mithgol