socketry / async-mysql

12 stars 3 forks source link

Mysql2::Error: This connection is still waiting for a result, try again once you have the result #3

Open Shiler opened 4 years ago

Shiler commented 4 years ago

I am trying to test how Falcon behaves in handling both blocking and non-blocking operations in parallel. I'm stuck making async-mysql gem work. I created an endpoint with the following logic:

def show
    ActiveRecord::Base.connection.execute('SELECT SLEEP(1)')
    render json: {}, status: :ok
end

Then I tested it using ab: 10 requests at a time. It starts to return Mysql2::Error: This connection is still waiting for a result, try again once you have the result error after a while. I also tested async-postgres and it works well processing both pg_sleep(1) and INSERT, DELETE, SELECT queries.

The issue seems to be a known one: single connection is being used by multiple actors. But I believe async-mysql provides fiber-aware connection pool out of the box.

Am I miss something or maybe it's a bug?

Rails 6.0.3.2 Ruby 2.7.0 MySQL 5.6 (max_connections = 1024) mysql2 0.5.3

database.yml:

adapter: async_mysql
pool: 1024
user: test
password: test
database: test_db
timeout: 5000
reconnect: true

command: RAILS_ENV=production bundle exec falcon --verbose serve --bind http://0.0.0.0:4000 (no matter forked or hybrid mode)

MySQL Workbench shows that only 4-18 connections of 1024 are used.

tleish commented 4 years ago

Not sure if it's related, but this seems similar to an issue around mysql2, fibers and em-synchrony.

https://github.com/brianmario/mysql2/pull/168

ioquatix commented 4 years ago

I'm working on this. The reality is, the mysql2 gem is not sufficient for non-blocking I/O. There is a new adaptor but it is not completed yet.

https://github.com/socketry/db-mariadb