Приветствуем, Хабровчане и Скорокодеры! В статье про разработку Scorocode мы спросили сообщество, какой новый функционал вы бы хотели увидеть в сервисе. Одним из популярных вариантов стала поддержка в серверном коде npm модулей. Вы просили — мы сделали! За подробностями просим под кат.
Кратко о реализации
Для внедрения npm модулей нам пришлось полностью пересмотреть устройство хранения файлов и скриптов. Мы отказались от хранения скриптов в стороннем облаке и перенесли все данные на свои сервера. Это позволило нам создать задел для реализации необходимого функционала, а также улучшить скорость работы с данными.
Дальше пришла очередь самого обработчика JS файлов. Данный обработчик (далее «брокер») слушает RabbitMQ и при поступлении задания передает его в пул воркеров для дальнейшей обработки. Сам брокер написан на Go и использует мост Go-V8 для выполнения JavaScript кода. Было понятно, что для поддержки npm модулей чистый V8 не подойдет, реализовывать по запросу самые популярные и необходимые модули тоже утопичная идея. В любом случае код должен был выполняться в NodeJS.
У многих наших конкурентов npm модули или не поддерживаются или поддерживаются из «белого списка». Мы сразу для себя определили, что хотим дать нашим пользователям полный доступ к npm, не ограничивая их какими-либо списками поддерживаемых модулей. Это заставило нас найти возможность запуска обработчиков изолированно от остальных, чтобы код не смог сломать чужие данные.
Для решения задачи изолированного запуска JavaScript кода мы выбрали Docker. Это позволило нам запускать обработку JavaScript кода в контейнере, и в дальнейшем не ограничивать пользователей в выборе модулей. Контейнер создается из образа при выполнении скрипта. Сам же скрипт и установленные модули пробрасываются в виде файла и папок внутрь контейнера. Дополнительно мы доработали нативную функцию require для того, чтобы она могла поддерживать пользовательские скрипты, установленные npm модули, а также нативные модули NodeJS.
Как мы оставили админа и разработчика без пива
Данная реализация была готова давно, тестировали мы её около недели и, на первый взгляд, всё работало без проблем. Стремясь порадовать пользователей как можно раньше, мы решили выкатить обновления в пятницу после обеда. После выкладки релиза, а также миграции данных, все работало на ура, пока наш разработчик не попробовал написать код, использующий setInterval.
Как оказалось, при использовании параметра timeout нативного модуля vm, песочница отрабатывает ровно столько, сколько нужно, но как только в нашем коде встречается setInterval, timeout не срабатывает. К сожалению, у нас не было времени разбираться с проблемой и после недолгих раздумий задача контроля времени выполнения скриптов была возложена на плечи самого брокера.
В итоге, релиз был выложен, исправлены возникшие проблемы, но выходные у нашего администратора и разработчика начались только в субботу в 1:58, поэтому о бокале пятничного пива в баре пришлось позабыть. Нарушать заповедь «не выкладывать релизы в пятницу» больше не будем :)
Как использовать npm модули в Scorocode
Для того, чтобы подключить необходимые модули, вам нужно перейти в раздел «Настройки приложения» и выбрать вкладку «npm зависимости».
В секции dependencies опишите все модули, которые вы собираетесь использовать. Свойство — название модуля, значение — необходимая версия (вы можете оставить значение версии пустым, в этом случае будет установлена последняя версия модуля).
{
"dependencies":{
"scorocode": "",
"underscore": "",
"async": ""
}
}
После чего нажимаем кнопку сохранить и переходим в раздел «Серверный код» и создаем новый скрипт:
Как видно из скриншота, использование установленных модулей ничем не отличается от использования в NodeJS. Для подключения необходимых модулей используется require.
var SC = require('scorocode');
var async = require('async');
var _ = require('underscore');
// Ваш код.....
Заключение
В целом нам удалось достаточно безболезненно реализовать поддержку npm модулей в приложениях пользователей. А теперь нам интересно получить обратную связь, как вы будете использовать данный функционал в своих приложения?
Также, учитывая ограничения npm, мы присматриваемся к поддержке пакетного менеджера для node.js от facebook yarn. Пробовал ли его кто-нибудь, какие есть мнения у вас на счёт него?
Поделиться с друзьями
Комментарии (3)
s1dd0k
18.10.2016 17:17-1Правильно я понимаю, что это просто Parse развернутый за деньги?
rockyou
18.10.2016 18:12Нет, это полностью собственная разработка. Подробнее мы описали разработку в двух статьях в блоге:
Обзор платформы
Статья про технические подробности разработки
eshimischi
По поводу yarn, заметная быстрота выполнения команды
и все зависимости устанавливаются в считанные мгновения. А второй раз еще быстрее, так как все файлы уже в кеше.