Deux réponses :
Réponse paresseuse : utilisez simplement une écriture bloquante. L'EM vous remet déjà des morceaux discrets de données, pas une chaîne gigantesque. Donc votre exemple d'implémentation est peut-être un peu faux. Êtes-vous sûr de vouloir créer un nouveau fichier temporaire pour chaque morceau de données qu'EM vous remet ? Cependant, je vais continuer en supposant que votre exemple de code fonctionne comme prévu.
Certes, l'approche paresseuse dépend du périphérique sur lequel vous écrivez, mais essayer d'écrire simultanément plusieurs grands flux sur le disque va constituer un goulot d'étranglement majeur et vous perdrez de toute façon les avantages d'avoir un serveur basé sur les événements. Vous vous retrouverez à jongler avec des recherches de disque dans tous les sens, les performances d'E/S chuteront, tout comme les performances de votre serveur. La gestion de plusieurs choses à la fois n'est pas un problème avec la RAM, mais dès que vous commencez à vous occuper de périphériques en bloc et de la planification des E/S, vous allez rencontrer des goulots d'étranglement au niveau des performances, quoi que vous fassiez.
Cependant, je suppose que vous pourriez vouloir effectuer de longues écritures sur le disque en même temps que vous voulez des réponses à faible latence à d'autres requêtes, non lourdes en termes d'IO. Donc, peut-être la bonne réponse :
Utilice différer .
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'
}
Oui, cela utilise l'enfilage. Ce n'est pas si grave dans ce cas : vous n'avez pas à vous soucier de la synchronisation entre les threads, car EM est assez gentil pour s'en occuper pour vous. Si vous avez besoin d'une réponse, utilisez la callback, qui sera exécutée dans le thread principal du réacteur lorsque le thread du travailleur aura terminé. De plus, la GIL n'est pas un problème dans ce cas, puisque vous avez affaire à un blocage d'E/S et que vous n'essayez pas d'obtenir la concurrence du CPU.
Mais si vous avez l'intention de tout écrire dans le même fichier, vous devrez faire attention avec defer, car le problème de synchronisation se posera car vos threads tenteront probablement d'écrire dans le même fichier au même moment.