Chakra — это JavaScript-движок, используемый в Microsoft Edge и универсальных Windows-приложениях. Начиная с Windows 8.1 и Windows Server 2012 R2, в Chakra появился новый набор API для встраивания (JavaScript Runtime, или JSRT API), позволяющий применять Chakra за рамками упомянутых клиентских сценариев.
Azure DocumentDB стал одним из первых сервисов со встроенной Chakra, используемой для нативной реализации скриптовых возможностей в движке баз данных. С недавним анонсом открытия ключевых компонетов Chakra (ChakraCore) на GitHub мы также рады поделиться нашим опытом и планами на будущее использование Chakra.
Использование JavaScript в NoSQL базе данных
Azure DocumentDB — это NoSQL сервис баз данных, оптимизированный для записи и ориентированный на работу с документами. Сервис изначатльно спроектирован так, чтобы нативно поддерживать работу с JSON и JavaScript. Происходящий от объектных выражений JavaScript, JSON часто используется при передаче структурированных и частично структурированных данных.
DocumentDB использует Chakra для реализации программируемых возможностей в серверной части, включая транзакционное исполнение логики на JavScript нативно внутри движка баз данных. Нам кажется, что подход с использованием JavaScript как современной альтернативы T-SQL предоставляет разработчикам естественный интерфейс для реализации бизнес-логики, выраженной в форме серверных скриптов (хранимые процедуры, тригерры и определяемые пользователем функции) в DocumentDB.
В качестве примера давайте посмотрим на хранимые процедуры, чтобы понять, как Chakra используется в DocumentDB. Как разработчики вы можете регистрировать и запускать хранимые процедуры, написанные на JavaScript, для осуществления пакетного или последовательного набора операций над многими документами, используя единую ACID-транзакцию. Когда тенант регистрирует хранимую процедуру, Chakra прекомпилирует ее в байт-код.
Далее, когда тенант запускает выполнение процедуры, среда исполнения Chakra выполняет соответствующий скрипт в своей песочнице с учетом существующих ресурсных ограничений. Среда исполнения реализует тесную интеграцию между программной моделью JavaScript и изолированным снимком состояния базы данных. До тех пор, пока хранимая процедура не завершилась успехом, все операции в базе данных реализуются в рамках единой транзакции. В случае возникновения исключительной ситуации в скрипте DocumentDB автоматически откатит всю транзакцию.
Давайте посмотрим подробнее на некоторые возможности Chakra и их использование в DocumentDB.
Аренда потоков
Chakra реализует модель аренды потоков, в рамках которой среда исполнения JavaScript всегда работает в одном потоке, но не привязана жестко к конкретному потоку. Другими словами, среда исполнения в каждый момент работает в одном потоке, но привязка к конкретному потоку может меняться со временем.
Аренда потоков хорошо подходит для DocumentDB, так как она управляет набором сред исполнения и может присваивать среду для каждого тенанта для выполнения JavaScript. Это позволяет избежать затрат на излишние инициализации новых сред исполнения на каждый тенант в то время, как DocumentDB может сохранять защищенность и изоляцию каждого тенанта.
Сериализация байт-кода
После регистрации серверного скрипта DocumentDB использует Chakra для предварительной компиляции и сериализации скрипта в байт-код. В нормальной цепочке исполнения JavaScript движку необходимо распарсить код, создать синтаксическое дерево и сгенерировать байт-код перед выполнением. Сериализация байт-кода в Chakra позволяет DocumentDB заранее обработать скрипт вплоть до генерации байт-кода и созранить закешированную копию для последующего повторного использования. Благодаря этому можно сэкономить на повторном анализе кода перед каждым исполнением, что дает существенных выигрыш в скорости исполнения.
API управления ресурсами
DocumentDB спроектирована как мульти-тенантный сервис, в котором строгое управление ресурсами и изоляция тенантов критичны для предотвращения «проблем назойливого соседства». Любые интегрированные компоненты должны реализовывать свою деятельность в рамках экстремально ограниченных системных ресурсов и интегрировать в общую систему управления ресурсов и изоляции тенантов в DocumentDB.
Если мы позволим одному из скриптов в тенанте потреблять дополнительные ресурсы, это может повлиять на производительность всех тенантов или даже нарушить работу всего сервиса. Chakra выставляет API, которые DocumentDB использует для решения этой проблемы, позволяя базе данных прерывать выполнение скрипта в случае, если потребление ресурсов CPU или памяти выходит за установленные пределы.
Переход на ChakraCore
Как вы знаете, команда Chakra недавно открыла ключевые компоненты движка в рамках проекта ChakraCore. ChakraCore реализует практически те же возможности, что и Chakra, и спроектирована как самодостаточный движок JavaScript, который будет в дальнейшем разрабатываться в открытом виде. Мы со стороны DocumentDB уже включили в планы миграцию с Chakra на ChakraCore в ближайшем будущем. Данный шаг позволит нам предоставить пользователям дополнительные преимущества, сохранив при этом озвученные выше возможности. Мы также планируем вносить свой вклад в развитие движка.
Возможности ECMAScript 6
Прошедший год был особенно замечательным для сообщества JavaScript, учитывая окончательное принятие стандарта ECMAScript 6 (ES6, или официально ES2015) — пожалуй самого значительного обновления JavaScript за всю историю. Разнообразие новых возможностей и синтаксические плюшки, реализованные в ES6, получили большое признание от сообщества.
ChakraCore уже реализует многие возможности ES6. Миграция DocumentDB на новый движок позволит разработчикам использовать еще более удобный JavaScript-код для работы с базами данных, например, упростить обработку данных используя промисы ES6. Ниже приведен пример хранимой процедуры с применением промисов и стрелочных функций из ES6:
function swapPlayerInventories(playerId1, playerId2) {
__.filter(document => {return document.id == playerId1 || document.id == playerId2;})
.then(playersToSwap => {
var player1 = playersToSwap[0], player2 = playersToSwap[1];
var player1ItemTemp = player1.item;
player1.item = player2.item;
player2.item = player1ItemTemp;
return __.replaceDocument(player1);
})
.then(() => __.replaceDocument(player2))
.catch(error => { throw 'Unable to update players, rollback transaction.';} );
}
И еще несколько слов
Использование Chakra было для нас большим успехом, мы с нетерпением ждем дальнейшие развите сервиса с миграцией на ChakraCore. Вики с инструкцией по встраиванию — это хорошая стартовая точка для изучения вопрос по интеграции ChakraCore в ваши приложения.
Если у вас есть отзывы для команды Chakra, вы можете открыть запрос на GitHub или обратиться к ним в твиттере @ChakraCore.
Подробнее узнать о программной модели DocumentDB со стороны сервера можно узнать на страницах документации. Если у вас есть вопросы по DocumentDB, свяжитесь с нами на форумах StackOverflow или запланируйте 1:1-чат с инженерной командой DocumentDB. Следить за свежими новостями и анонсами новых возможностей можно в нашем твиттере @DocumentDB.
Автор: Microsoft