how to solve 'connection is still waiting for a result' error with em_mysql2

别来无恙 提交于 2019-12-07 06:26:03

问题


I'm using activerecord with em_mysql2 under Goliath (eventmachine). The oddest thing is happening with my User model. When I do a POST to /users the first time, it all works just find as expected. When I do a second POST I get an error.

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

This doesn't happen for any other of my models or routes. I would assume that if the db connection is in a messed up state that I would see the same error on other requests but nope - all the other DB update and GET requests seem to work just fine.

Does anyone understand how it is that this could only happen for my Users model and only for a User.save action? Does active record somehow store the DB connection that it used for doing a Model.save and re-use it?

EDIT:

I somehow failed to mention when I wrote this question that I was using ActiveRecord as the ORM. I also failed to mention that I was asynchronously sending a request to a Mongo database to fetch the user authentication information.

My solution:

It turns out that the only time this error would occur was when the response from Mongo came back before the response from MySQL, which caused the MySQL response to be picked up by a different Fiber than the one that made the request. Since the MySQL2 fiber implementation I was using used the objectID of the fiber to manage the connections, that seems to have caused the issue.

Overall connection pooling in ActiveRecord + MySql2 + Fibers + Goliath wasn't a fully supported config. (There may be some progress since that time though)


回答1:


Use a connection pool, which comes with em-synchrony. Using only one connection fails here because requests come in from Goliath while a MySQL query is still waiting for a result, as you can't have multiple active queries on a single connection.

Wrap the connection like this instead:

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

The pool makes sure that requests wait until a connection becomes available, should all connections be in use.

The size of the connection pool needs to be tuned though, depending on what your database can handle and how much traffic you're expecting. I started out with something around 5-10 but it was a relatively low traffic service, at least in the beginning. That made our connection woes go away.



来源:https://stackoverflow.com/questions/6145821/how-to-solve-connection-is-still-waiting-for-a-result-error-with-em-mysql2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!