Estoy tratando de hacer que una parte de un solo subproceso sea multiproceso. El código de subproceso único inicial funciona bien, pero después de colocarlo en un subproceso, el servidor se bloquea sin ninguna información de registro en la consola.
Versión inicial:
data_array.each do |data| service = SomeService.new(data) data['answers'] = service.answer_data endVersión de subprocesos múltiples:
threads = [] threads << Thread.new { data_array.each do |data| service = SomeService.new(data) data['answers'] = service.answer_data end } threads.each(&:join)Intenté binding.pry y obtuve más información:
Class llamada AggregationReport < ReportSomeService intentó ejecutar AggregationReport.new , quedó atascado allí para siempre.Por favor, ayúdame a entender lo que está sucediendo aquí, ¡cualquier idea/ayuda sería muy apreciada!
Versión Ruby: Ruby27x Rieles: 5.2
Estoy haciendo algunas suposiciones sobre por qué está enhebrando esto, pero esperaría que el código de enhebrado típico siga la siguiente estructura básica:
threads = data_array.map do |data| Thread.new { SomeService.new(data).answer_data } end answers = threads.map(&:value)Para cada pieza de trabajo que necesita hacer:
Si su servicio necesita una conexión a la base de datos (p. ej., postgres, redis, etc.), también deberá administrarla. Para activerecord, agregue ActiveRecord::Base.with_connection{ } dentro del hilo para asignar una conexión db. Hay enfoques similares para Redis/etc. Luego, asegúrese de tener suficientes conexiones para el número de subprocesos que desea crear (mire el pool: configuración en config/database.yml ).
Thread.new { ActiveRecord::Base.with_connection{ SomeService.new(data).answer_data } }Por esta y otras razones, no siempre es una buena idea generar N subprocesos, por lo que en lugar de este enfoque, puede considerar usar un grupo de subprocesos de X y asegurarse de tener un grupo de conexiones de base de datos de al menos X + 1 conexiones. Todo esto puede ser complejo. Hay grandes gemas que se asientan sobre el enhebrado de rubí y hacen que sea más fácil hacer exactamente este tipo de cosas. Recomiendo encarecidamente comprobar concurrent-ruby (incluido con Rails).