Skip to content

Commit

Permalink
Fix Timeout interrupt handling on Ruby 2.3 and protect Mysql2::Statem…
Browse files Browse the repository at this point in the history
…ent#execute

Timeout::ExitException was removed in Ruby 2.3.0, 2.2.3, and 2.1.8,
in favor of Timeout::Error. Backwards compatible aliases are provided
for Ruby 2.1.x and 2.2.x, but not earlier verions.

With thanks to @jeremy for PR brianmario#671 and @yui-knk for PR brianmario#677, this commit
also protects prepared statements from being interrupted, so the compat
shim is in Mysql2::Util.
  • Loading branch information
sodabrew committed May 7, 2016
1 parent 2652fdb commit e103318
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
17 changes: 17 additions & 0 deletions lib/mysql2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ module Mysql2::Util
def self.key_hash_as_symbols(hash)
return nil unless hash
Hash[hash.map { |k,v| [k.to_sym, v] }]

#
# In Mysql2::Client#query and Mysql2::Statement#execute,
# Thread#handle_interrupt is used to prevent Timeout#timeout
# from interrupting query execution.
#
# Timeout::ExitException was removed in Ruby 2.3.0, 2.2.3, and 2.1.8,
# but is present in earlier 2.1.x and 2.2.x, so we provide a shim.
#
if Thread.respond_to?(:handle_interrupt)
require 'timeout'
# rubocop:disable Style/ConstantName
TimeoutError = if defined?(::Timeout::ExitException)
::Timeout::ExitException
else
::Timeout::Error
end
end

end
2 changes: 1 addition & 1 deletion lib/mysql2/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def self.default_query_options

if Thread.respond_to?(:handle_interrupt)
def query(sql, options = {})
Thread.handle_interrupt(Timeout::ExitException => :never) do
Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
_query(sql, @query_options.merge(options))
end
end
Expand Down
3 changes: 1 addition & 2 deletions spec/mysql2/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,7 @@ def connect *args
}.should raise_error(Mysql2::Error)
end


it 'should be impervious to connection-corrupting timeouts ' do
it 'should be impervious to connection-corrupting timeouts in #query' do
pending('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
# attempt to break the connection
expect { Timeout.timeout(0.1) { @client.query('SELECT SLEEP(1)') } }.to raise_error(Timeout::Error)
Expand Down

0 comments on commit e103318

Please sign in to comment.