2011-05-26 12 views
5

Estoy usando activerecord con em_mysql2 bajo Goliath (eventmachine). Lo más extraño está sucediendo con mi modelo de Usuario. Cuando hago una POST a/users la primera vez, todo funciona solo para encontrar lo que se espera. Cuando hago un segundo POST recibo un error.cómo resolver el error de 'conexión aún está esperando un resultado' con em_mysql2

Mysql2::Error: This connection is still waiting for a result, try again once you have the result: INSERT INTO `users` (... and so on ...) 

Esto no ocurre con ningún otro de mis modelos o rutas. Supongo que si la conexión de db está en un estado desordenado, vería el mismo error en otras solicitudes, pero no, todas las otras solicitudes de actualización y GET de DB parecen funcionar bien.

¿Alguien entiende cómo es que esto solo podría suceder para mi modelo de usuarios y solo para una acción de User.save? ¿El registro activo almacena de alguna manera la conexión de base de datos que utilizó para hacer un modelo.guardar y volver a usarlo?

EDIT:

de alguna manera yo no mencionó cuando escribí esta pregunta que yo estaba usando ActiveRecord como el ORM. Tampoco mencioné que estaba enviando de forma asíncrona una solicitud a una base de datos de Mongo para obtener la información de autenticación del usuario.

Mi solución:

Resulta que la única vez que este error ocurriría fue cuando la respuesta de Mongo regresó antes de que la respuesta de MySQL, lo que provocó la respuesta de MySQL para ser recogido por un diferente Fibra que la que hizo la solicitud. Dado que la implementación de fibra MySQL2 que estaba utilizando usa el objectID de la fibra para administrar las conexiones, eso parece haber causado el problema.

La agrupación de la conexión general en ActiveRecord + MySql2 + Fibers + Goliath no era una configuración totalmente compatible. (Sin embargo, puede haber algún progreso desde ese momento)

Respuesta

0

Utilice un grupo de conexiones, que viene con sincronía em. El uso de una sola conexión falla aquí porque las solicitudes provienen de Goliath mientras que una consulta MySQL aún espera un resultado, ya que no puede tener múltiples consultas activas en una sola conexión.

Envuelva la conexión de esta forma:

db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do 
    Mysql2::EM::Client.new 
end 

La piscina se asegura de que las solicitudes de esperar hasta que se disponga de una conexión, todas las conexiones deben estar en uso.

Sin embargo, el tamaño del grupo de conexiones debe ajustarse, dependiendo de lo que su base de datos pueda manejar y de cuánto tráfico esté esperando. Empecé con algo entre 5 y 10 pero era un servicio de tráfico relativamente bajo, al menos al principio. Eso hizo que nuestros problemas de conexión desaparecieran.

+0

Gracias! En general, esa es una respuesta razonable a la pregunta. Lamentablemente, no puedo validar su corrección en este momento dado que me mudé a un proyecto diferente. Si alguien más puede validar, me gustaría aceptar la respuesta ... ¡Oh! ¿Estás usando ActiveRecord? – radixhound

+0

No, no usando ActiveRecord, pero Sequel. Una historia bastante similar, así que sospecho que la solución es la misma. – roidrage

+0

@radixhound ¿Cómo lo resolvería si usara ActiveRecord – Anand

Cuestiones relacionadas