как отправить действительно очень большой объект json в качестве ответа - node.js с помощью экспресс

Я получаю эту ошибку FATAL ERROR: JS Allocation failed - process out of memory, и я определил, что проблема заключается в том, что я отправляю действительно очень большой объект json в res.json (или JSON.stringify). Чтобы дать вам некоторый контекст, я в основном отправляю около 30 000 файлов конфигурации (каждый файл конфигурации имеет около 10 000 строк) как один объект json

Мой вопрос: есть ли способ отправить такой огромный объект json или есть лучший способ его потоковой передачи (например, с помощью socket.io?)

Я использую: узел v0.10.33, экспресс@4.10.2

ОБНОВЛЕНИЕ: пример кода

var app = express();

app.route('/events')
.get(function(req, res, next) {
  var configdata = [{config:<10,000 lines of config>}, ... 10,000 configs]
  res.json(configdata); // The out of memory error comes here
})

person abarik    schedule 12.05.2015    source источник
comment
Можете ли вы дать небольшой пример кода?   -  person Evan Hahn    schedule 13.05.2015
comment
я добавил пример кода кода   -  person abarik    schedule 13.05.2015
comment
Конечно, ответ НЕ в том, чтобы отправлять 30 000 файлов конфигурации за раз? Это запах кода. Даже 1 загрузка json с 10000 строками — это много.   -  person BenjaminPaul    schedule 13.05.2015
comment
да, я согласен... это был плохой дизайн кода. я исправил это с помощью socket.io для потоковой передачи файла конфигурации, а не для отправки всего сразу   -  person abarik    schedule 13.05.2015
comment
Кроме того, поскольку я сохраняю каждый файл конфигурации как запись в базе данных, я не могу выполнять потоковую передачу построчно. плюс, прочитав эту статью, я вижу, что 10 тысяч строк в одном файле конфигурации можно прочитать все сразу josh.zeigler.us/technology/web-development/   -  person abarik    schedule 13.05.2015


Ответы (3)


После долгих попыток я, наконец, решил использовать socket.io для отправки каждого файла конфигурации за раз, а не всех файлов конфигурации одновременно. Это решило проблему нехватки памяти, которая приводила к сбою моего сервера. Спасибо за всю твою помощь

person abarik    schedule 13.05.2015

Попробуйте использовать потоки. Что вам нужно, так это читаемый поток, который производит данные по запросу. Я напишу здесь упрощенный код:

var Readable = require('stream').Readable;
var rs = Readable();

rs._read = function () {
    // assuming 10000 lines of config fits in memory
    rs.push({config:<10,000 lines of config>);
};

rs.pipe(res);
person Magomogo    schedule 14.05.2015

Вы можете попробовать увеличить доступный узел памяти с помощью флаг --max_old_space_size в командной строке.

Возможно есть более элегантное решение. Моей первой реакцией было предложить использовать res.json() с объектом Buffer, а не пытаться отправить весь объект за один раз, но потом я понял, что все, что конвертируется в JSON, вероятно, в любом случае захочет использовать весь объект сразу. Таким образом, у вас закончится память, даже если вы переключаетесь на поток. Или, по крайней мере, это то, что я ожидал.

person Trott    schedule 12.05.2015
comment
ну, я, конечно, могу строить по одному файлу конфигурации за раз, и это нормально. проблема возникает, когда я пытаюсь сопоставить 10 000 файлов конфигурации (каждый файл конфигурации имеет 10 000 лайков). Можете ли вы указать мне пример использования объекта буфера. В противном случае, я думаю, я выберу метод потоковой передачи socket.io... - person abarik; 13.05.2015