diff --git a/.rubocop.yml b/.rubocop.yml index d41d8d923..d68b7fd17 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -26,3 +26,7 @@ Style/TrailingCommaInLiteral: Style/TrivialAccessors: AllowPredicates: true + +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index d12f2c180..69bc12164 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -16,7 +16,7 @@ VALUE cMysql2Client; extern VALUE mMysql2, cMysql2Error, cMysql2TimeoutError; -static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream; +static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream, sym_read_timeout; static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow; static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args; @@ -639,7 +639,10 @@ static VALUE do_query(void *args) { int retval; VALUE read_timeout; - read_timeout = rb_iv_get(async_args->self, "@read_timeout"); + read_timeout = rb_hash_aref(rb_iv_get(async_args->self, "@current_query_options"), sym_read_timeout); + if (NIL_P(read_timeout)) { + read_timeout = rb_iv_get(async_args->self, "@read_timeout"); + } tvp = NULL; if (!NIL_P(read_timeout)) { @@ -1452,6 +1455,7 @@ void init_mysql2_client() { sym_as = ID2SYM(rb_intern("as")); sym_array = ID2SYM(rb_intern("array")); sym_stream = ID2SYM(rb_intern("stream")); + sym_read_timeout = ID2SYM(rb_intern("read_timeout")); sym_no_good_index_used = ID2SYM(rb_intern("no_good_index_used")); sym_no_index_used = ID2SYM(rb_intern("no_index_used")); diff --git a/spec/mysql2/client_spec.rb b/spec/mysql2/client_spec.rb index 00d9c17db..abdb4fbe6 100644 --- a/spec/mysql2/client_spec.rb +++ b/spec/mysql2/client_spec.rb @@ -963,6 +963,20 @@ def run_gc end.not_to raise_error end + context 'with query-level timeout' do + it "time outs on long queries" do + expect do + @client.query("select sleep(2)", read_timeout: 1) + end.to raise_error(Mysql2::Error::TimeoutError) + end + + it "does not time out on queries under timeout" do + expect do + @client.query("select sleep(1)", read_timeout: 2) + end.not_to raise_error + end + end + context 'write operations api' do before(:each) do @client.query "USE test"