2011-03-29 15 views
5

Aquí hay una pregunta abierta, por lo que primero describiré el problema. Tenemos un trabajador Resque que se supone que debe sacar los trabajos de sincronización de datos de una cola, las razones son dos, usar suposiciones Cron (y pagar el tiempo de arranque del entorno Rails una y otra vez), y las colas alternativas, bien hechas por Github un muy buen caso en contra de ellos cuando announced Resque. Además, la funcionalidad de series de tiempo Redis ya desempeña una parte importante de nuestra infraestructura, donde también barajamos datos TS a RRDtool & etc ...¿ActiveRecord no puede volver a conectarse cuando se ejecuta dentro de la aplicación bifurcada/roscada?

Aquí está el problema, con un típico de tres horas entre puestos de trabajo (pero el personal puede programar trabajos en cualquier momento ... de ahí la cola), el servidor PostgreSQL se va. Lo suficientemente fácil de curar, esperaba que establecer reconnect: true en el entorno correspondiente garantizaría que esto funcionara como esperaba ... Leí en un fewplaces que reconnect: true no funcionará para las aplicaciones que usan fork(). Lo cual, naturalmente, Resque, para empezar son los trabajadores ... la parte que no entiendo es por qué la reconexión de ActiveRecord no puede funcionar en estas circunstancias?

me di cuenta de las implementaciones de la reconnect!MySQL Adapter y la PostgreSQL Adapter en ActiveRecord son diferentes ... pero de cualquier manera yo esperaría que la configuración de ActiveRecord reconnect: true para trabajar.

El problema parece ser suficiente, cuando existe el proceso hijo, se cierra el archivo de asas creada por el padre clara (que cuelga de este modo la conexión con la base de datos) - ¿es posible cerrar un gestor de archivo en tal forma en que ActiveRecord no reconoce que la conexión se ha terminado?

También hay, por lo que vale la pena, una ActiveRecord aware fork() cual pude encontrar en Github, como pastie - es no probado, pero supongo que funciona (no lo he probado con los carriles actuales ..)

Mi pregunta es más, ¿Por qué la reconexión automática en AR no funciona si fork()? (y, últimamente, no puedo ser la única persona que tiene este problema; lo estoy atribuyendo al uso de PGSQL con Resque!)

Respuesta

6

Aunque no es exactamente la respuesta a "¿por qué no se puede reconectar? ", pero creo que lo que puede ayudar es el siguiente código poner en algún lugar en la fase de inicialización:


Resque.after_fork do |job| 
    ActiveRecord::Base.connection.reconnect! 
end 

actualización: en cuanto a la reconexión - parece que es única característica de MySQL. Así es como se usa en el adaptador mysql: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb#L848 Como puede ver, utiliza la función de reconexión del controlador subyacente. https://github.com/kwatch/mysql-ruby/blob/master/ext/mysql.c#L923

Por otro lado, el adaptador de PostgreSQL no hacer nada con respecto a reconnect opción, se puede ver el https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

Además, el sitio PostgreSQL dice explícitamente que "bifurcar un proceso con conexión abierta libpq puede conducir a resultados impredecibles "- http://www.postgresql.org/docs/9.0/interactive/libpq-connect.html Y también es evidente que el controlador C no proporciona ninguna función de reconexión.

+0

Roman, seguro - Tengo la solución, pero estoy buscando específicamente la razón por la reconexión: true no funciona.Me pregunto si se trata de concurrencia (indicador de 'allowconcurrency' de activerecord) y de reconocer que la primera conexión todavía está conectada ... pero realmente estoy perdido. –

+0

Bueno, al mirar el código activerecord, lo que puedo decir es que la opción 'reconectar' no es compatible con el adaptador PostgreSQL. – Roman

+0

Roman, ¿puede ser más específico, tal vez un enlace? Hubo una implementación en algún lugar que encontré ... (Estoy seguro) –

Cuestiones relacionadas