tl; dr Sinatra funciona bien con Threads, pero es probable que deba utilizar un servidor web diferente.
Sinatra en sí mismo no impone ningún modelo de simultaneidad, ni siquiera maneja la simultaneidad. Esto lo hace el manejador de Rack (servidor web), como Thin, WEBrick o Passenger. Sinatra en sí mismo es seguro para subprocesos, lo que significa que si su controlador de Rack usa varios subprocesos para las solicitudes del servidor, funciona bien. Sin embargo, dado que Ruby 1.8 solo admite subprocesos verdes y Ruby 1.9 tiene un bloqueo de VM global, los subprocesos no son muy utilizados para la simultaneidad, ya que en ambas versiones, los subprocesos no se ejecutarán verdaderamente en paralelo. La voluntad, sin embargo, en JRuby o el próximo Rubinius 2.0 (ambas implementaciones alternativas de Ruby).
La mayoría de los racks existentes que usan hilos usarán un grupo de subprocesos para volver a utilizar los subprocesos en lugar de crear un subproceso para cada solicitud entrante, ya que la creación de subprocesos no es gratis, esp. en 1.9 donde los hilos mapean 1: 1 a hilos nativos. Los hilos verdes tienen mucha menos sobrecarga, razón por la cual las fibras, que básicamente son hilos verdes programados cooperativamente, tal como se utilizaba en la sinatra-sincronía antes mencionada, se volvieron tan populares recientemente. Debe tener en cuenta que cualquier comunicación de red tendrá que pasar por EventMachine, por lo que no puede usar la gema mysql
, por ejemplo, para hablar con su base de datos.
Las fibras se adaptan bien para el procesamiento intensivo de la red, pero fallan miserablemente en cálculos pesados. Es menos probable que te encuentres en condiciones de carrera, una trampa común con concurrencia, si usas fibras, ya que solo hacen un cambio de contexto en puntos claramente definidos (con sincronización, cada vez que esperas IO). Hay un tercer modelo de concurrencia común: Procesos. Puede usar el servidor de precompresión o iniciar múltiples procesos usted mismo. Si bien esto parece una mala idea a primera vista, tiene algunas ventajas: en la implementación normal de Ruby, esta es la única forma de usar todas sus CPU al mismo tiempo. Y evita el estado compartido, por lo que no hay condiciones de carrera por definición. Además, las aplicaciones multiproceso se escalan fácilmente en varias máquinas. Tenga en cuenta que puede combinar procesos múltiples con otros modelos de concurrencia (evented, cooperative, preventive).
La elección se hace principalmente por el servidor y middleware que utilice:
- multi-proceso, no preforking: Mestizo, Fino, WEBrick, Zbatery
- Multi-Proceso, preforking: unicornio, arco iris , Pasajero
- evented (adecuado para Sinatra-sincronía): Thin iris, Zbatery
- Threaded: Net :: HTTP :: Server, roscado Mongrel, Puma, arco iris, Zbatery, Thin [1], Phusion Passenger Enterprise >= 4
[1] desde Sinatra 1.3.0, Thin se iniciará en modo enhebrado, si es iniciado por Sinatra (es decir, con ruby app.rb
, pero no con el comando thin
, ni con rackup
).
Por supuesto, no puede continuar debido a '.join' que se bloqueará hasta que se termine cada subproceso - vea: http://ruby-doc.org/core-1.9/classes/Thread.html#M001331 – asaaki
Bueno, eso fue un ejemplo, en realidad puedo estar haciendo una llamada para leer un archivo o un URI usando HTTP Net y no dentro de un hilo específicamente. ¿Qué sucede si no quiero que se bloquee otra solicitud? – ch4nd4n
Sin generar más instancias, no veo ninguna solución fácil. Normalmente usaría thin o unicornio para tener instancias múltiples. Si solo desea tener algo de trabajo en segundo plano (por lo tanto, no importa si el resultado de la llamada al recurso externo se muestra inmediatamente), realmente debería usar trabajos en segundo plano (resque, trabajos retrasados, ...) y Si estos trabajos terminaron, los resultados se pueden mostrar en una solicitud adicional. El problema general es que, en la mayoría de los casos, las aplicaciones de Ruby no pueden ser realmente multiproceso, ya que la resonancia magnética aún no es compatible con varios núcleos. Engendrar/Bifurcar es una solución alternativa. – asaaki