¿Rails es multi-hilo o no?

Hola, creo que la respuesta es que NO. Más que nada por algún mensaje
que he
leido en esta lista diciendo que ahora no lo es y que esa es una de las
pegas que se le puede poner al Framework.
Bien, estoy leyendo un tutorial de Ruby, y me encuentro con que Ruby es
multi-hilo.

first = Thread.new() do
myindex = 0
while(myindex < 10):
puts “Thread One!”
sleep 3
myindex += 1
end
end

second = Thread.new() do
myindex2 = 0
while(myindex2 < 5):
puts “Thread Two!”
sleep 5
myindex2 += 1
end
end

third = Thread.new() do
myindex3 = 0
while(myindex3 < 2):
puts “Thread Three!”
sleep 10
myindex3 += 1
end
end

first.join()
second.join()
third.join()

Si no estoy confundido el Objeto Thread es lo que se llama hilo ¿NO?
Lo que hace este codigo es ir alternado la salida por consola de los
puts de
los 3 bloques ( “Thread One!”, “Thread Two!”, “Thread One!”,…“Thread
Three!”,…) así hasta que
se acaben los while.

¿Esto es un proceso multi-hilo en ruby?
¿Me estoy haciendo la picha un lio?

No tengo claro eso de que rails NO es multi-thread.

cualquier aclaración será bien recibida

Un saludo

El Tuesday 20 January 2009 11:49:41 Andrés gutiérrez escribió:

sleep 3

end

¿Esto es un proceso multi-hilo en ruby?
¿Me estoy haciendo la picha un lio?

No tengo claro eso de que rails NO es multi-thread.

cualquier aclaración será bien recibida

Un saludo

A partir de la version 2.2 (la ultima en estos momentos) sí que es
multihilo.
Antes no, pero no porque ruby no tuviera hilos, si no porque el codigo
de
rails no era seguro en hilos (thread safe), si la ejecucion de un hilo
puede
afectar a otro hilo entonces no es thread safe y eso es lo que pasaba
antes
de la 2.2


Sergio Cambra .:: entreCables - Symbol Servicios Informáticos S.L. ::.
Nicolás Guillén 6, locales 2 y 3. 50.018 Zaragoza
T) 902 021 404 F) 976 52 98 07 E) [email protected]

Lo mejor que he leído sobre el tema es este post de Pratik Naik:
http://m.onkey.org/2008/10/23/thread-safety-for-your-rails

El 20/01/2009, a las 11:49, Andrés gutiérrez escribió:

Hola, creo que la respuesta es que NO. Más que nada por algún
mensaje que he leido en esta lista diciendo que ahora no lo es y que
esa es una de las pegas que se le puede poner al Framework.

Rails < 2.2 No ThreadSafe (Vamos que no es seguro que funcione con
hilos)
Rails >= ThreadSafe

Sin embargo, los drivers de la base de datos, hasta donde se no lo
son, por lo que aunque existan varios threads pululando por la
aplicación, cuando intentan acceder a la base de datos, se ponen en
fila para ir uno en uno. Existen soluciones a este problema, pero
ahora mismo, no se como está.

Si no estoy confundido el Objeto Thread es lo que se llama hilo ¿NO?

Creo que si.

¿Esto es un proceso multi-hilo en ruby?

Si y no.

¿Me estoy haciendo la picha un lio?

No. Creo que vas bien.

Además, sin nos ponemos pijoteros, ruby no tiene threads de
verdad( entendiendo de verdad como cpu threads), ruby tiene green
threads. Los green threads suelen tener la ventaja de ser más rápidos,
por tener cambios de contexto más lijeros, pero si es el SSOO el que
maneja los threads, puede casi-ejecutar simultaneamente los threads
gracias a las modernas cps que nos acompañan en estos días. Es solo
una observación. Depende del caso el rendimiento de uno u otro.

Pero lo anterior es solo cierto para ruby mri, ya que otras
implementaciones como jruby utilizan threads de verdad. Hay gente que
dice que da más rendimiento los threads sobre java. En mis pruebas,
nunca fue así, pero estas cosas cambian muy rápido.

Un Saludo


Guillermo Álvarez Fernández
[email protected]
http://cientifico.net

Vale, he leido el link que has dejado Raul [1]. y yo, que estoy
empezando,
me quedo con esto (porque todo lo que haga en principio serán tonterias
de
pedir y dar a la BBDD que para mi ya será todo un logro):

"I think the situation is different with Ruby/Rails. Probably many
programmers writing Rails apps today don’t know much about monitors, *
semaphores*, mutexes and threading issues. Luckily usually they
don’t
have to, because each request gets its own set of instances of
controllers
and views, so you’r threadsafe there (it’s different to most Java
frameworks
where requests run concurrently in the controllers).

Short story: I very much appreciate threadsafety, much I think it will
take
a year or so until everything (Rails core plus the average set of
plugins)
is mature enough."
En cualquier caso, no me veo capaz de asimilar todas las opiniones que
hay
en el post [1]. No tengo el background suficiente. Pero pienso que las
cosas, hoy por hoy, no estan del todo claras en cuanto al tema del
thread-safe. Si el Team Rails ya ha dicho que podemos usarlo, pero los
que
comentan en el post [1] No lo terminan de ver claro. también dicen que
los
TEST que hay en el core de rails no contemplan situaciones multi-hilo.

En cualquier caso, gracias Raul por el enlace. Me ha dejado claro que es
un
tema complicado, y que desde mi poca experiencia, intentaré hacer App
sencillas. “Intentaré hilar fino” :slight_smile:

Por cierto, ¿alguien puede poner un ej. de una App rails que tenga
necesariamente que usar multi-hilo (sea real o un ej. ficticio)?

[1] http://m.onkey.org/2008/10/23/thread-safety-for-your-rails

Guillermo:
green threads, este concepto no lo conocía, pero esta bien saber que lo
que
hace ruby es como una pequeña mentirijilla :slight_smile: No?

Hola,

Me ha dejado claro que es un tema complicado, y que desde mi poca
experiencia, intentaré hacer App
sencillas. “Intentaré hilar fino” :slight_smile:

Una sabia decisión… el multithread en cualquier lenguaje de
programación es un asunto complicado. Los hay que facilitan el proceso
más que otros, pero al final tienes que tener muy claro lo que
estáshaciendo y es una potencial fuente de problemas. Si no lo necesitas, no
lo uses.

Por cierto, ¿alguien puede poner un ej. de una App rails que tenga
necesariamente que usar multi-hilo (sea real o un ej. ficticio)?
Habría varios casos en los que sería potencialmente interesante.

Un ejemplo podría ser el siguiente. Imagina que estás ejecutando Rails
en modo “de toda la vida” con un único thread por acción y tienes una
acción que necesita recuperar cinco queries no relacionadas (noticias,
feeds, últimos usuarios, tagcloud y categorías, por ejemplo).

Trabajando con un único thread, esa action va a lanzar las 5 queries
secuencialmente, y al final muestra el resultado. En este caso podías
establecer varias conexiones, por ejemplo 5, en un pool de conexiones, y
lanzar un thread por cada una de las queries, usando una conexión en
cada una.

De esta forma, la acción sólo va a esperar el tiempo que le lleve hacer
la query más larga.

Te vale la pena complicarte la vida con eso? probablemente no, porque si
tienes una acción que lanza cinco queries potencialmente costosas lo que
tienes que hacer es cachear el resultado de la acción o dividirla, pero
bueno… es un ejemplo

saludos,


javier ramírez

…i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
…you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez

Solo para aportar algo sobre el cuidado que hay que tener al trabajar
con
threads: #125 Dynamic Layouts - RailsCasts

Saludos!

Perdón, esta es la corrección que le hacen a Ryan B. en su episodio:

layout :set_layout

def load_blog
@current_blog = Blog.find_by_subdomain(current_subdomain)
if @current_blog.nil?
flash[:error] = “Blog invalid”
redirect_to root_url
end
end

def set_layout
@current_blog ? @current_blog.layout_name || ‘application’ :
‘application’
end

Alguien me puede explicar porque este código es thread-safe? No lo veo

El 20 de enero de 2009 15:33, Ruben. D. [email protected]
escribió:

Que buen ejemplo !!! lo he pillado perfectamente, y si lo supiera hacer
lo
haría multi-hilo.

“la acción sólo va a esperar el tiempo que le lleve hacer la query más
larga”

En un escenario mono-hilo: “La acción duraría la suma de las 5 querys”
¿es
asi?

En cualquier caso, en mis prioridades esta primero aprender a cachear
antes
que hacer cositas multi-hilo

Gracias
El 20 de enero de 2009 14:05, javier ramirez
[email protected]escribió:

Paul, from my understanding, the layout is global state, and setting
global state directly in a request is a bad thing to do since this is
shared between threads. Setting it in one thread will effect another.

¿Rollo variables globales que un hilo machaca al otro?
Yo me planto. algo he entendido, pero me queda grande el tema. Espero
vover
en otro momento a retomarlo con una mayor perspectiva.

2009/1/20 Dani D. [email protected]

2009/1/20 Andrés gutiérrez [email protected]:

end
end

def set_layout
@current_blog ? @current_blog.layout_name || ‘application’ : ‘application’
end

Alguien me puede explicar porque este código es thread-safe? No lo veo
En los comentarios:

  1. Ryan B. Sep 02, 2008 at 22:35
    @Paul, from my understanding, the layout is global state, and setting
    global state directly in a request is a bad thing to do since this is
    shared between threads. Setting it in one thread will effect another.

Someone please correct me if I’m wrong.

Dani
Doni

On Tue, Jan 20, 2009 at 6:16 PM, Andrés gutiérrez
[email protected] wrote:

¿Rollo variables globales que un hilo machaca al otro?
Yo me planto. algo he entendido, pero me queda grande el tema. Espero vover
en otro momento a retomarlo con una mayor perspectiva.

Si va por ahi.

Los threads en Rails son por request, cada request tiene su propia
instancia del controlador que toca, por lo que no te has de preocupar
de sincronizar el estado del controlador.

Pero clase solo hay una por proceso, si configuras algo a nivel de
clase todos los threads ven el cambio.

Los threads en Rails son por request, cada request tiene su propia
instancia del controlador que toca, por lo que no te has de preocupar
de sincronizar el estado del controlador.

Muy aclarador el por que rails ha podido sobrevivir hasta ahora sin ser
multi-hilo. Porque vive en la web y aquí casi todo son simples request
(pido
a la App y ella me da o cambio algo y ella lo cambia pero todo
en la misma petición ¿no?. No sé si esto que he dicho es correcto, pero
Xavier, yo si que he entendido lo que tu has dicho.

Pero clase solo hay una por proceso, si configuras algo a nivel de
clase todos los threads ven el cambio.

Esto no lo pillo del todo. Todo son clases en Rails. Quiero decir que un
controlador es lo mismo que un modelo. Clases que heredan de sus padres
ActionController y ActionModel respectivamente ¿no?
¿Configurar algo a nivel de clase?
¿Que se configura a nivel de clase?
¿las variables de clase es algo que comparten todas las instancias de
los
controladores?

No te ralles mucho conmigo y disculpa mi ignorancia.

El 20 de enero de 2009 21:19, Xavier N. [email protected] escribió:

2009/1/20 Andrés gutiérrez [email protected]

2009/1/20 Andrés gutiérrez [email protected]:

Muy aclarador el por que rails ha podido sobrevivir hasta ahora sin ser
multi-hilo. Porque vive en la web y aquí casi todo son simples request (pido
a la App y ella me da o cambio algo y ella lo cambia pero todo
en la misma petición ¿no?. No sé si esto que he dicho es correcto, pero
Xavier, yo si que he entendido lo que tu has dicho.

Asi es. Las aplicaciones multiproceso en ese sentido son sencillas
porque todo esta muy claro: cada request entra por un proceso que no
comparte memoria con el resto. Como necesitan compartir datos se usa
un servidor de base de datos.

Yo por el momento no tengo previsto usar multi-thread en Rails.

No te ralles mucho conmigo y disculpa mi ignorancia.

Nada nada todos fuimos ignorantes un dia u otro, que esto no viene
builtin en el cerebro por obra del espiritu santo :-).

Por un lado tenemos las clases:

class UsersController < ApplicationController; end

y por otro sus instancias, una instancia el controllador ese, que es
quien sabe gestionar requests relativas a usuarios.

En modo multi-thread Rails lanza un thread nuevo por request y en ese
thread va una instancia de la clase UsersController.

Pero la clase misma quedó definida cuando ruby interpretó el fichero
users_controller.rb. Esto significa que la máquina virtual tiene una
entidad llamada UsersController en algun lugar. Es una entidad que tú
creas en el código de manera implícita con el keyword “class”.

Esa entidad es única en la máquina virtual, y tiene cosas asociadas
como son variables de clase:

@@layout

Al tratarse de una entidad única todos los threads la comparten (la
clase UsersController es la misma en todo el proceso), y en particular
comparten los datos asociados a ella.

Dicho esto, al menos en edge en un vistazo asi rapido no me parece que
un layout especificado como simbolo setee nada a nivel de clase.

El día 21 de enero de 2009 9:54, Andrés gutiérrez
[email protected]
escribió:> Xavier, si me contestas, por favor respondeme solo a lo que te pregunto,

porque si metes algún concepto que no conozca no me voy a poder resistir
a preguntarte…esto de rails es un puto vicio |-)

Jajajaja, a mí en estas cosas la curiosidad me parece una virtud, y si
encima cuentas con alguien con tanta paciencia como Xavier el hilo
puede ser interminable :smiley:

Sólo comentarte que imho en este punto tus preguntas tienen respuesta
en el propio código fuente de Rails y que, aunque de primeras uno se
puede sentir intimidado, si te centras en la parte que te interesa es
más o menos fácil trazar cómo funciona. Por tu evolución en la lista
yo diría que estás más que preparado para algo así, no te dejes
impresionar :slight_smile:

Te animo a que, armado con un licorcito/refresco y ruby-debug, te
crees una aplicación de ejemplo, congeles rails en vendor y le
dediques un rato a depurar cómo se gestionan los layouts. Por propia
experiencia te aseguro que despejarás las dudas, cogerás más confianza
y aprenderás bastante ruby por el camino :slight_smile: Y de paso le das unos
minutos más de tiempo libre a Xavier, que se los ha ganado XD

+1 a Esta
recomendación,
mirar el codigo de rails “por dentro” ayuda bastante tanto a pillarle
el pulso al framework como al propio ruby. Es tiempo bien empleado.

Saludos,

Isaac Feliu

Al tratarse de una entidad única todos los threads la comparten (la
clase UsersController es la misma en todo el proceso), y en particular
comparten los datos asociados a ella.

Esos datos asociados a ella: ¿te refieres a las variables de clase ej.:
@@layout?

Dicho esto, al menos en edge en un vistazo asi rapido no me parece que
un layout especificado como simbolo setee nada a nivel de clase.

Especificado como simbolo: ¿Quieres decir cuando en el controller pones
:layout?
Setee nada a nivel de clase: ¿Qué se guarde en una variable de clase @@?
Si
esto es correcto, ¿es por eso que ahora rails es multi-hilo?
Rails ya no depende de las variables de clase para definir :layout ahora
en
edge?

Xavier, si me contestas, por favor respondeme solo a lo que te pregunto,
porque si metes algún concepto que no conozca no me voy a poder resistir
a preguntarte…esto de rails es un puto vicio |-)

Cuando te canses de contestar a mi curiosidad, me cortas…y punto, o no
me
contestas… :slight_smile:
Si no me queda claro hoy, ya me quedara mañana, pero que nadie se me
enfade
por ser tan pregunton

El 21 de enero de 2009 1:07, Xavier N. [email protected] escribió:

Por tu evolución en la lista
yo diría que estás más que preparado para algo así, no te dejes
impresionar :slight_smile:
Me parece que te he engañado, soy un poco cobarde, y si que he leido
cosas,
pero casi no me he manchado las manos con el código
pero todo es empezar. Aunque lo de crear una App rails…me había
propuesto
estar unos meses sin tocar rails, sólo leer y tocar ruby a pelo
pero si es por aprender ruby, hare lo que me recomiendas, o al menos lo
intentaré…en poco aparecerá un hilo sobre esto (espero que no muy
OFF-TOPIC) :slight_smile:

Sólo una cosa, para asegurarme de lo que me has dicho:
Si mo lo he entendido mal:
1- licorcito/refresco: Coca-cola (uhmm!!!).
2- ruby-debug. He leido algo, pero…¿para que lo uso?¿Viene con ruby o
hay
descargarlo?
3- congeles rails en vendor. Lo googleare, es cambiar una linea ¿No?
4- Le dediques un rato a depurar cómo se gestionan los layouts: ¿Esto
como
lo hago? ¿Por que lado de las entrañas miro?

Yo creo que me podré aclarar en el cómo hacerlo, otra cosa es que saque
cosas en claro…ya veremos :slight_smile:

Gracias

El 21 de enero de 2009 10:20, Isaac Feliu Pérez
[email protected]escribió:

El día 21 de enero de 2009 10:35, Andrés gutiérrez
[email protected]
escribió:> Me parece que te he engañado, soy un poco cobarde, y si que he leido cosas,

pero casi no me he manchado las manos con el código
pero todo es empezar.

A eso me refería, las preguntas teóricas están muy bien pero a veces
lo mejor es meterle mano al código, ver qué tiene esta variable, qué
pasa si cambio esta línea por esta otra, qué hace este bucle tan raro,
por qué han creado una clase aparte para esto…

Aunque lo de crear una App rails…me había propuesto
estar unos meses sin tocar rails, sólo leer y tocar ruby a pelo
pero si es por aprender ruby, hare lo que me recomiendas, o al menos lo
intentaré…en poco aparecerá un hilo sobre esto (espero que no muy
OFF-TOPIC) :slight_smile:

Bueno, te lo recomendaba porque tú preguntabas sobre el caso concreto
de rails. De todas formas, en una charla sobre cómo contribuir a Rails
Juanjo Bazán dijo una gran verdad: si juegas con el código de rails
seguro que aprenderás mucho ruby.

Sólo una cosa, para asegurarme de lo que me has dicho:
Si mo lo he entendido mal:
1- licorcito/refresco: Coca-cola (uhmm!!!).

Perfecto :smiley:

2- ruby-debug. He leido algo, pero…¿para que lo uso?¿Viene con ruby o hay
descargarlo?

Me lo has puesto a huevo :wink:

3- congeles rails en vendor. Lo googleare, es cambiar una linea ¿No?

Hay una tarea rake que te permite copiar la versión de rails que
tienes instalada como gema en el sistema al directorio /vendor de tu
aplicación. De esa forma puedes trastear sobre el código de rails sin
miedo a cargarte nada: si rompes algo puedes borrar ese /vendor/rails
y restaurarlo de nuevo y tus gemas permanecen a salvo.

4- Le dediques un rato a depurar cómo se gestionan los layouts: ¿Esto como
lo hago? ¿Por que lado de las entrañas miro?

Yo empezaría buscando la función layout en el código fuente, a partir de la doc:
http://api.rubyonrails.org/classes/ActionController/Layout/ClassMethods.html#M000314

Yo creo que me podré aclarar en el cómo hacerlo, otra cosa es que saque
cosas en claro…ya veremos :slight_smile:

Seguro que sí, es cuestión de dejarse llevar por la curiosidad y tirar
del hilo (igual que en la lista de correo, pero preguntándole al
propio código) :slight_smile: