Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/mysql2/em.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

module Mysql2
module EM
class ReadTimeout < ::RuntimeError; end

class Client < ::Mysql2::Client
module Watcher
def initialize(client, deferable)
Expand Down Expand Up @@ -41,6 +43,9 @@ def query(sql, opts = {})
if ::EM.reactor_running?
super(sql, opts.merge(async: true))
deferable = ::EM::DefaultDeferrable.new
if @read_timeout
deferable.timeout(@read_timeout, Mysql2::EM::ReadTimeout.new)
end
@watch = ::EM.watch(socket, Watcher, self, deferable)
@watch.notify_readable = true
deferable
Expand Down
18 changes: 18 additions & 0 deletions spec/em/em_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@
end.to raise_error('some error')
end

it "should timeout if we wait longer than :read_timeout" do
errors = []
EM.run do
client = Mysql2::EM::Client.new DatabaseCredentials['root'].merge(read_timeout: 1)
defer = client.query "SELECT sleep(2)"
defer.callback do
# This _shouldn't_ be run, but it needed to prevent the specs from
# freezing if this test fails.
EM.stop_event_loop
end
defer.errback do |err|
errors << err
EM.stop_event_loop
end
end
expect(errors).to eq([Mysql2::EM::ReadTimeout.new])
end

context 'when an exception is raised by the client' do
let(:client) { Mysql2::EM::Client.new DatabaseCredentials['root'] }
let(:error) { StandardError.new('some error') }
Expand Down