diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-11-27 11:54:59 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-27 11:54:59 +0900 |
commit | 0e2cd3d749dadcdb5027d48399aea02ef74815f3 (patch) | |
tree | e3a8bbc17d2b33a0c373c7aa9343079f2f9999e9 /activerecord/test/cases/adapters | |
parent | ad0630f0ae2d65bc0adda4097af8009a985b6f15 (diff) | |
download | rails-0e2cd3d749dadcdb5027d48399aea02ef74815f3.tar.gz rails-0e2cd3d749dadcdb5027d48399aea02ef74815f3.tar.bz2 rails-0e2cd3d749dadcdb5027d48399aea02ef74815f3.zip |
Add new error class `QueryCanceled` which will be raised when canceling statement due to user request (#31235)
This changes `StatementTimeout` to `QueryCanceled` for PostgreSQL.
In MySQL, errno 1317 (`ER_QUERY_INTERRUPTED`) is only used when the
query is manually cancelled.
But in PostgreSQL, `QUERY_CANCELED` error code (57014) which is used
`StatementTimeout` is also used when the both case. And, we can not tell
which reason happened.
So I decided to introduce new error class `QueryCanceled` closer to the
error code name.
Diffstat (limited to 'activerecord/test/cases/adapters')
-rw-r--r-- | activerecord/test/cases/adapters/mysql2/transaction_test.rb | 27 | ||||
-rw-r--r-- | activerecord/test/cases/adapters/postgresql/transaction_test.rb | 31 |
2 files changed, 56 insertions, 2 deletions
diff --git a/activerecord/test/cases/adapters/mysql2/transaction_test.rb b/activerecord/test/cases/adapters/mysql2/transaction_test.rb index da4b73a0da..cb183cc54c 100644 --- a/activerecord/test/cases/adapters/mysql2/transaction_test.rb +++ b/activerecord/test/cases/adapters/mysql2/transaction_test.rb @@ -116,5 +116,32 @@ module ActiveRecord end end end + + test "raises QueryCanceled when canceling statement due to user request" do + assert_raises(ActiveRecord::QueryCanceled) do + s = Sample.create!(value: 1) + latch = Concurrent::CountDownLatch.new + + thread = Thread.new do + Sample.transaction do + Sample.lock.find(s.id) + latch.count_down + sleep(0.5) + conn = Sample.connection + pid = conn.query_value("SELECT id FROM information_schema.processlist WHERE info LIKE '% FOR UPDATE'") + conn.execute("KILL QUERY #{pid}") + end + end + + begin + Sample.transaction do + latch.wait + Sample.lock.find(s.id) + end + ensure + thread.join + end + end + end end end diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb index ebba0f0c1c..c24dfeb345 100644 --- a/activerecord/test/cases/adapters/postgresql/transaction_test.rb +++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb @@ -120,8 +120,8 @@ module ActiveRecord end end - test "raises StatementTimeout when statement timeout exceeded" do - assert_raises(ActiveRecord::StatementTimeout) do + test "raises QueryCanceled when statement timeout exceeded" do + assert_raises(ActiveRecord::QueryCanceled) do s = Sample.create!(value: 1) latch1 = Concurrent::CountDownLatch.new latch2 = Concurrent::CountDownLatch.new @@ -148,6 +148,33 @@ module ActiveRecord end end + test "raises QueryCanceled when canceling statement due to user request" do + assert_raises(ActiveRecord::QueryCanceled) do + s = Sample.create!(value: 1) + latch = Concurrent::CountDownLatch.new + + thread = Thread.new do + Sample.transaction do + Sample.lock.find(s.id) + latch.count_down + sleep(0.5) + conn = Sample.connection + pid = conn.query_value("SELECT pid FROM pg_stat_activity WHERE query LIKE '% FOR UPDATE'") + conn.execute("SELECT pg_cancel_backend(#{pid})") + end + end + + begin + Sample.transaction do + latch.wait + Sample.lock.find(s.id) + end + ensure + thread.join + end + end + end + private def with_warning_suppression |