множественные записи в потоке записи в node.js

#file-io #node.js #eventemitter

#файл-ввод-вывод #node.js #отправитель событий #file-io

Вопрос:

Я просматривал код node-dirty и заметил, что при записи большого количества данных в файл исходный программист решил объединить записи в несколько групп и выполнять записи в группах по одной за раз, но все они выполняются одновременно как часть одного цикла, без ожидания каких-либо обратных вызовов. У меня есть три вопроса по этому поводу. У меня есть похожая проблема, которую нужно решить.

  1. Является ли это в некотором роде более эффективным? Должен ли я также объединять записи?
  2. Как мне следует выбрать оптимальный размер пакета? Почему бы просто не записать одну группу?
  3. Если я подпишусь на событие on (‘drain’) в потоке записи, будет ли оно отправлено только один раз после завершения всех одновременно выполненных операций записи? Или после каждой? (я предполагаю, что первое)
  4. Если выдается сообщение on (‘ошибка’), будет ли также выдано событие (‘слив’)? Или они взаимоисключающие?

Спасибо

Комментарии:

1. Можете ли вы показать ссылку на часть node-dirty, которая делает это. Ссылка

Ответ №1:

Является ли это в некотором роде более эффективным? Должен ли я также объединять записи?

Неэффективно выполнять много небольших операций записи. отправка команды записи связана с накладными расходами. Таким образом, запись всего 5 байт вместо 1000 обходится дороже.

Как мне выбрать оптимальный размер пакета? Почему бы просто не написать одну группу?

Оптимальный размер звучит для меня как черное дело. Я предполагаю, что есть веские причины для того, чтобы не делать из этого одну большую запись. Вероятно, чтобы начать запись раньше, чем позже. Немного эффективнее начать немного раньше.

Если я подпишусь на событие on (‘drain’) в потоке записи, будет ли оно отправлено только один раз после завершения всех одновременно выполненных операций записи? Или после каждого? (я предполагаю, что первое)

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

Если выдается сообщение on (‘ошибка’), будет ли также выдано событие (‘слив’)? Или они взаимоисключающие?

Даже если он генерируется, не имеет смысла выполнять обработку ошибок в ‘drain’. Если произошла ошибка, я бы всегда предполагал, что вся операция записи завершилась неудачно, и не пытался восстановить запись в середине.

Комментарии:

1. чтобы уточнить, я не собираюсь обрабатывать ошибку в drain. но у меня есть обработчик успеха в drain. Я просто хочу убедиться, что он не запущен 🙂

2. @Vishnu тогда все должно быть в порядке. Я все же дважды проверю источник

Ответ №2:

Для 4. Если выдается сообщение on (‘ошибка’), будет ли также выдано событие (‘слив’)? Или они взаимоисключающие?

Вас это беспокоит, поскольку вы не хотите правильно поддерживать состояние в своем приложении. Итак, возможно, вы могли бы использовать удобную функцию:

 function not_if(proc, veto_inner) {
  var vetoed = false;
  return {
    proc: function() {
      if (!vetoed) { return proc.apply(null, arguments); }
    }, 
    vetoer: function() {
      if (!vetoed) {
        vetoed = true;
        veto_inner.apply(null, arguments);
    }
  };
}
  

Теперь вы можете установить для обработчика ‘error’ значение ‘vetoer’, а для обработчика ‘drain’ значение ‘proc’ и не беспокоиться о том, что ‘drain’ вызывается после ‘error’.