Потоковые файлы из обработчика EventMachine? - PullRequest
1 голос
/ 10 ноября 2010

Я создаю сервер потоковой передачи событий. Я беспокоюсь о том, чтобы избежать блокировки ввода-вывода или сделать что-нибудь еще, чтобы испортить цикл событий.

Из того, что я прочитал, неблокирующий ввод-вывод ruby ​​можно использовать для потоковой передачи файлов неблокирующим способом, или я могу вызвать next_tick, но мне немного неясно, какой из этих подходов предпочтительнее. 1003 *

Отчасти проблема в том, что я не нашел хорошего объяснения неблокирующих функций библиотеки ввода-вывода в ruby.

Короткая версия : Предполагая длительную работу сетевого ввода-вывода, несколько минут настенных часов потоковой передачи на файл, передачу, каков наилучший способ сделать это в Eventmachine, не смешивая цикл обработки событий?

  while 1 do
    file.read do |bytes|
      @conn.send_data bytes
    end
  end

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

1 Ответ

1 голос
/ 06 января 2012

Я думаю, что вы все еще можете использовать FileStreamer. FileStreamer ожидает, что его первый аргумент будет Connection, но это свободный контракт. Пока вы реализуете методы, которые ожидает FileStreamer, он должен работать. Взгляните на это

https://gist.github.com/f4d997c3eeb6bdc5a9f3

Методы, которые вам нужно обработать, это send_data и send_file_data. Вы можете выполнять свои манипуляции здесь. Затем передайте результат в EM :: Connection.

Кроме того, из моего прочтения кода, специальным свойством FileStreamer является то, что он выделяет файл с отображенной памятью (если файл не маленький). По сути, вы можете сделать то же самое, открыв обычный Ruby-файл, читая из него блоки, выполняя манипуляции и эмулируя поведение FileStreamer.stream_one_chunk. Что в основном:

  • Каждая итерация должна либо отправлять некоторые данные в Соединение, либо перепланировать себя, используя next_tick
  • Данные могут многократно записываться в Соединение, пока не будет заполнен исходящий буфер (согласно get_outbound_data_size)
  • Как только файл полностью прочитан, его следует закрыть (конечно)

На самом деле, мне кажется, что лучше не использовать FileStreamer, если ваш файл не будет удобно помещаться в памяти.

Вы можете посмотреть на EM :: Protocols для идей о том, как преобразовать данные во время их потоковой передачи.

...