Почему org/arangodb/request синхронен?

Почему новый модуль JavaScript запрос является синхронным? Предполагается ли, что он используется только в очереди заданий?

Есть ли способ сделать асинхронные запросы http (s) в ArangoDB?


person Christian Pekeler    schedule 19.03.2015    source источник
comment
Этот вопрос не должен откладываться. Это действительно из-за другой встроенной операционной среды. На самом деле очень законно....   -  person Brian Vanderbusch    schedule 20.03.2015
comment
@ Брайан Вандербуш: не путайте действительное или законное с темой. Конечно, этот вопрос может быть правильным - он просто неуместен здесь, потому что ОП запрашивает внешние ресурсы. Полное удаление этой части сделало бы вопрос актуальным, но также сделало бы ваш ответ устаревшим.   -  person BoltClock    schedule 25.03.2015
comment
@BoltClock спасибо за разъяснение   -  person Brian Vanderbusch    schedule 25.03.2015
comment
@BoltClock Я переформулировал вопрос, чтобы он соответствовал правилам. ОП просил не внешние ресурсы, а способ выполнения асинхронных запросов (который не поддерживается платформой, поэтому четкий ответ на внешние ресурсы: их нет и никогда не будет).   -  person Alan Plum    schedule 15.04.2015
comment
@pluma: Выглядит хорошо, спасибо за ваше редактирование.   -  person BoltClock    schedule 15.04.2015


Ответы (1)


Полное раскрытие: я являюсь частью команды разработчиков ArangoDB и в основном работаю над Foxx и всем JavaScript. Я также написал модуль org/arangodb/request.


ArangoDB — это среда, отличная от Node.js, несмотря на то, что у них много общего (например, использование движка JavaScript V8). В отличие от Node.js (или браузера), ArangoDB использует модель параллелизма на основе потоков и не имеет цикла событий. Однако потоки не отображаются в JavaScript (и фактически в V8 каждый поток полностью изолирован), поэтому обычно вам даже не нужно думать о них.

В браузере и в Node.js такие функции, как setTimeout, работают, задерживая выполнение кода через цикл событий (пока не пройдет определенное время или пока не произойдет внешнее событие).

В ArangoDB код всегда выполняется линейно. Например, входящие HTTP-запросы передаются контроллерам Foxx в JavaScript, и ответ отправляется, как только контроллер возвращается. Даже если бы вы могли использовать setTimeout, внешние ресурсы, с которыми вы работали (или даже «внутренние» ресурсы, такие как коллекции документов и транзакции), вероятно, уже исчезли бы к тому времени, когда отложенный код мог бы выполняться.

Из-за этого функция request, предоставляемая модулем org/arangodb/request, также полностью синхронна. Вместо возврата промиса или обратного вызова он напрямую возвращает входящие данные ответа. Это также явно не тот же модуль, что и request в npm, а скорее синхронная реализация, основанная на API этого модуля в той мере, в какой реализация его API возможна вне Node.js (например, без включения потоков и возврата удаленный ответ вместо приема обратных вызовов).

Если вы работали с Node.js/io.js, это может показаться неправильным, потому что неблокирующий ввод-вывод может обеспечить более высокую пропускную способность, но имейте в виду, что цели разработки ArangoDB и Node.js очень разные. Node.js построен на потоках и сетевых подключениях. ArangoDB построена как постоянное хранилище данных и вместо этого должна иметь дело с транзакциями и блокировками.

Вероятно, не самая лучшая идея обращаться к внешним API напрямую с ваших контроллеров Foxx, если у вас высока вероятность серьезной сетевой задержки или если ответ внешнего API не важен для ответа клиента. Для этого и нужны очереди Foxx. Ярким примером этого являются транзакционные электронные письма.

Хотя Foxx очень универсален, его основное внимание уделяется тому, чтобы позволить вам перемещать большую часть вашего приложения (особенно логику, которая выигрывает от приближения к данным) непосредственно в базу данных. Для проектов малого и среднего масштаба вы, вероятно, можете обойтись без внешних вызовов API. Но если ваше приложение в первую очередь связано с общением с другими службами по сети, выполнение этого кода в базе данных, вероятно, не является оптимальным решением.

К счастью, ArangoDB хорошо сочетается с другими, поэтому легко переместить ваш ресурсоемкий сетевой код из Foxx, если вы обнаружите, что он становится узким местом в производительности при более высоких нагрузках. Foxx не устраняет необходимость в серверах приложений, но может значительно уменьшить их сложность.


В качестве исправления к ответу Брайана: к сожалению, обещания также не позволят вам писать асинхронный код в синхронной среде. В Promises/A+ spec обещания должны выполняться асинхронно. Там, где они изначально не поддерживаются, их все равно нужно создавать поверх существующих функций, таких как setTimeout или process.nextTick, ни одна из которых не реализована в ArangoDB.

person Alan Plum    schedule 15.04.2015
comment
Спасибо за регистрацию и помощь в повторном открытии и рассмотрении этого вопроса, а также за ответ. Также ценю, что вы обратили внимание на то, что было не так с моим ответом. Документы аранго потрясающие. Я знал, что Foxx не использует узел из-за однопоточности, вызывающей проблемы с остальной частью Arango, но я не знал о синхронной природе Foxx поверх V8. Дает мне лучшее представление о том, как использовать системные ресурсы при принятии решения о масштабировании Arango. - person Brian Vanderbusch; 18.04.2015
comment
@BrianVanderbusch Спасибо за отзыв. Если вы обнаружите в документации что-то, что можно улучшить, не стесняйтесь открыть вопрос на GitHub или связаться со мной по IRC. Извините, если я столкнулся с более резким, чем предполагалось. - person Alan Plum; 24.04.2015