Use TCP_NODELAY if supported; Remove file descriptor ops from the tight loop; Cleanup timeout assignment; Split the threaded test suite in native and c to avoid a large number of active Threads affecting results.Add experimental Mysql#socket_type which typically returns 'socket (x)', but may be helpful for debugging purposes.
This commit is contained in:
parent
6c2b9ecb84
commit
6884d454bc
23
ext/mysql.c
23
ext/mysql.c
@ -271,9 +271,12 @@ static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
|
||||
myp->connection = Qtrue;
|
||||
|
||||
my_bool was_blocking;
|
||||
|
||||
vio_blocking(myp->handler.net.vio, 0, &was_blocking);
|
||||
myp->blocking = vio_is_blocking( myp->handler.net.vio );
|
||||
|
||||
vio_fastsend( myp->handler.net.vio );
|
||||
|
||||
myp->query_with_result = Qtrue;
|
||||
rb_obj_call_init(obj, argc, argv);
|
||||
|
||||
@ -762,6 +765,14 @@ static VALUE socket(VALUE obj)
|
||||
return INT2NUM(m->net.fd);
|
||||
}
|
||||
|
||||
/* socket_type */
|
||||
static VALUE socket_type(VALUE obj)
|
||||
{
|
||||
MYSQL* m = GetHandler(obj);
|
||||
VALUE description = vio_description( m->net.vio );
|
||||
return NILorSTRING( description );
|
||||
}
|
||||
|
||||
/* blocking */
|
||||
static VALUE blocking(VALUE obj){
|
||||
return ( GetMysqlStruct(obj)->blocking ? Qtrue : Qfalse );
|
||||
@ -825,28 +836,27 @@ static VALUE async_query(int argc, VALUE* argv, VALUE obj)
|
||||
|
||||
send_query(obj,sql);
|
||||
|
||||
if (NIL_P(timeout)) {
|
||||
timeout = m->net.read_timeout;
|
||||
}
|
||||
timeout = ( NIL_P(timeout) ? m->net.read_timeout : INT2NUM(timeout) );
|
||||
|
||||
VALUE args[1];
|
||||
args[0] = timeout;
|
||||
|
||||
struct timeval tv = { tv_sec: timeout, tv_usec: 0 };
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&read);
|
||||
FD_SET(m->net.fd, &read);
|
||||
|
||||
for(;;) {
|
||||
ret = rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
rb_sys_fail(0);
|
||||
rb_raise(eMysql, "query: timeout");
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (readable(1, (VALUE *)args, obj) == Qtrue) {
|
||||
if ( vio_poll_read( m->net.vio, INT2NUM(timeout) ) == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2147,6 +2157,7 @@ void Init_mysql(void)
|
||||
rb_define_method(cMysql, "readable?", readable, -1);
|
||||
rb_define_method(cMysql, "blocking?", blocking, 0);
|
||||
rb_define_method(cMysql, "socket", socket, 0);
|
||||
rb_define_method(cMysql, "socket_type", socket_type, 0);
|
||||
rb_define_method(cMysql, "refresh", refresh, 1);
|
||||
rb_define_method(cMysql, "reload", reload, 0);
|
||||
rb_define_method(cMysql, "select_db", select_db, 1);
|
||||
|
@ -15,7 +15,8 @@ Gem::Specification.new do |s|
|
||||
"Rakefile",
|
||||
"lib/mysqlplus.rb",
|
||||
"test/test_helper.rb",
|
||||
"test/threaded_test.rb",
|
||||
"test/native_threaded_test.rb",
|
||||
"test/c_threaded_test.rb",
|
||||
"test/evented_test.rb",
|
||||
"ext/error_const.h",
|
||||
"ext/extconf.rb",
|
||||
|
@ -1,26 +1,9 @@
|
||||
require File.dirname(__FILE__) + '/test_helper'
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, small overhead" ) do |test|
|
||||
ThreadedMysqlTest.new( 10, "Threaded, C, very small overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 0.1
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, medium overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 1
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, large overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 3
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, random overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = :random
|
||||
test.per_query_overhead = 0.005
|
||||
test.c_async_query = true
|
||||
test.run!
|
||||
end
|
||||
|
@ -1,5 +1,11 @@
|
||||
require File.dirname(__FILE__) + '/test_helper'
|
||||
|
||||
EventedMysqlTest.new( 10, "Evented, very small overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 0.005
|
||||
test.run!
|
||||
end
|
||||
|
||||
EventedMysqlTest.new( 10, "Evented, small overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 0.1
|
||||
|
31
test/native_threaded_test.rb
Normal file
31
test/native_threaded_test.rb
Normal file
@ -0,0 +1,31 @@
|
||||
require File.dirname(__FILE__) + '/test_helper'
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, very small overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 0.005
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, small overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 0.1
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, medium overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 1
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, large overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = 3
|
||||
test.run!
|
||||
end
|
||||
|
||||
ThreadedMysqlTest.new( 10, "Threaded, native Ruby, random overhead" ) do |test|
|
||||
test.setup{ Mysql.real_connect('localhost','root') }
|
||||
test.per_query_overhead = :random
|
||||
test.run!
|
||||
end
|
@ -13,7 +13,8 @@ class MysqlTest
|
||||
:start,
|
||||
:done,
|
||||
:c_async_query,
|
||||
:per_query_overhead
|
||||
:per_query_overhead,
|
||||
:timeout
|
||||
|
||||
def initialize( queries, context = '' )
|
||||
@queries = queries
|
||||
@ -21,6 +22,7 @@ class MysqlTest
|
||||
@done = []
|
||||
@c_async_query = false
|
||||
@per_query_overhead = 3
|
||||
@timeout = 20
|
||||
yield self if block_given?
|
||||
end
|
||||
|
||||
@ -186,7 +188,7 @@ class ThreadedMysqlTest < MysqlTest
|
||||
|
||||
log "sending query on connection #{conn}"
|
||||
|
||||
c_or_native_async_query( @connections[conn], "select sleep(#{@per_query_overhead})" ).each do |result|
|
||||
c_or_native_async_query( @connections[conn], "select sleep(#{@per_query_overhead})", @timeout ).each do |result|
|
||||
log "connection #{conn} done"
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user