Два ответа:
Ленивый Ответ: просто использовать блокирующий запись. EM уже передает вам дискретные куски данных, а не одну гигантскую строку. Таким образом, ваш пример реализации может быть немного выключен. Вы уверены, что хотите создать новый временный файл для каждого отдельного фрагмента, который EM вам нравится? Тем не менее, я продолжу с предположения, что ваш пример кода работает по назначению.
Понятно, что ленивый подход зависит от устройства, на которое вы пишете, но попытка одновременного написания нескольких больших потоков на диск будет одним из основных узких мест, и вы потеряете преимущества наличия события основанный сервер. Вы просто закончите работу с жонглирующим диском во всем мире, производительность IO резко упадет, и производительность вашего сервера тоже будет. Работа с множеством вещей сразу остается в порядке с ОЗУ, но как только вы начнете работать с блочными устройствами и планированием ввода-вывода, вы столкнетесь с узкими местами производительности, независимо от того, что вы делаете.
Однако, возможно, вы захотите сделать некоторые длинные записи на диск в то же время, что вы хотите, чтобы ответы с низкой задержкой на другие тяжелые запросы, отличные от IO. Итак, возможно, хороший ответ:
Использование defer.
require 'rubygems'
require 'tempfile'
require 'eventmachine'
module ExampleServer
def receive_data(data)
operation = proc do
begin
f = Tempfile.new('random')
f.write(data)
ensure
f.close
end
end
callback = proc do
puts "I wrote a file!"
end
EM.defer(operation, callback)
end
end
EventMachine::run {
EventMachine::start_server "127.0.0.1", 8081, ExampleServer
puts 'running example server on 8081'
}
Да, это использует резьбу. В этом случае это не так уж плохо: вам не нужно беспокоиться о синхронизации между потоками, потому что EM достаточно хорош, чтобы справиться с этим для вас. Если вам нужен ответ, используйте обратный вызов, который будет выполняться в потоке основного реактора, когда рабочий поток завершится. Кроме того, GIL является чем-то вроде не-проблемы для этого случая, поскольку вы имеете дело с блокировкой ввода-вывода здесь и не пытаетесь добиться параллелизма между процессорами.
Но если вы намеревались написать все в один файл, вам придется быть осторожным с отсрочкой, так как проблема синхронизации возникнет, так как ваши потоки, скорее всего, попытаются записать в один и тот же файл одновременно.
Крис, спасибо за ваш ответ. [Этот ответ] (http://stackoverflow.com/questions/2749503/what-is-the-best-way-to-read-files-in-an-eventmachine-based-app) через tmm1 конфликтует с тем, что документы скажем (или я неправильно понимаю). В основном я пытаюсь сделать очень простой перенос файлов (чтение из сокета и запись его на диск) ... – Andreas