2008-09-05 17:23:47 +00:00
|
|
|
require 'rubygems'
|
2008-09-05 23:54:48 +00:00
|
|
|
require 'mysqlplus'
|
|
|
|
|
|
|
|
class MysqlTest
|
|
|
|
|
|
|
|
class NotImplemented < StandardError
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_accessor :queries,
|
2008-09-08 16:45:00 +00:00
|
|
|
:context,
|
2008-09-05 23:54:48 +00:00
|
|
|
:connections,
|
|
|
|
:connection_signature,
|
|
|
|
:start,
|
2008-09-06 16:17:06 +00:00
|
|
|
:done,
|
2008-09-10 00:26:01 +00:00
|
|
|
:query_with,
|
2008-09-09 23:33:18 +00:00
|
|
|
:per_query_overhead,
|
|
|
|
:timeout
|
2008-09-05 23:54:48 +00:00
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
def initialize( queries, context = '' )
|
2008-09-05 23:54:48 +00:00
|
|
|
@queries = queries
|
2008-09-08 16:45:00 +00:00
|
|
|
@context = context
|
2008-09-05 23:54:48 +00:00
|
|
|
@done = []
|
2008-09-10 00:26:01 +00:00
|
|
|
@query_with = :async_query
|
2008-09-08 16:45:00 +00:00
|
|
|
@per_query_overhead = 3
|
2008-09-09 23:33:18 +00:00
|
|
|
@timeout = 20
|
2008-09-05 23:54:48 +00:00
|
|
|
yield self if block_given?
|
|
|
|
end
|
|
|
|
|
|
|
|
def setup( &block )
|
|
|
|
@start = Time.now
|
|
|
|
@connection_signature = block
|
|
|
|
end
|
|
|
|
|
|
|
|
def run!
|
2008-09-06 16:17:06 +00:00
|
|
|
c_or_native_ruby_async_query do
|
2008-09-08 16:45:00 +00:00
|
|
|
present_context if context?
|
2008-09-08 16:27:11 +00:00
|
|
|
prepare
|
|
|
|
yield
|
2008-09-06 16:17:06 +00:00
|
|
|
end
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
def per_query_overhead=( overhead )
|
|
|
|
@per_query_overhead = ( overhead == :random ) ? rand() : overhead
|
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
2008-09-05 23:54:48 +00:00
|
|
|
def prepare
|
|
|
|
raise NotImplemented
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
raise NotImplemented
|
|
|
|
end
|
|
|
|
|
|
|
|
def log( message, prefix = '' )
|
|
|
|
puts "[#{timestamp}] #{prefix} #{message}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def with_logging( message )
|
|
|
|
log( message, 'Start' )
|
|
|
|
yield
|
|
|
|
log( message, 'End' )
|
|
|
|
end
|
|
|
|
|
|
|
|
def timestamp
|
|
|
|
Time.now - @start
|
|
|
|
end
|
2008-09-08 16:45:00 +00:00
|
|
|
|
|
|
|
def context?
|
|
|
|
@context != ''
|
|
|
|
end
|
2008-09-05 23:54:48 +00:00
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
def present_context
|
|
|
|
log "#############################################"
|
|
|
|
log "# #{@context}"
|
|
|
|
log "#############################################"
|
|
|
|
end
|
2008-09-06 16:17:06 +00:00
|
|
|
|
|
|
|
def c_or_native_ruby_async_query
|
2008-09-10 00:26:01 +00:00
|
|
|
if @query_with == :c_async_query
|
2008-09-06 16:17:06 +00:00
|
|
|
log "** using C based async_query"
|
|
|
|
else
|
|
|
|
log "** using native Ruby async_query"
|
|
|
|
end
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
|
2008-09-10 00:26:01 +00:00
|
|
|
def dispatch_query( connection, sql, timeout = nil )
|
|
|
|
connection.send( @query_with, sql, timeout )
|
2008-09-08 00:48:47 +00:00
|
|
|
end
|
|
|
|
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
class EventedMysqlTest < MysqlTest
|
|
|
|
|
|
|
|
attr_accessor :sockets
|
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
def initialize( queries, context = '' )
|
2008-09-05 23:54:48 +00:00
|
|
|
@sockets = []
|
|
|
|
@connections = {}
|
2008-09-08 16:45:00 +00:00
|
|
|
super( queries, context )
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def setup( &block )
|
|
|
|
super( &block )
|
|
|
|
with_logging 'Setup connection pool' do
|
|
|
|
@queries.times do
|
|
|
|
connection = @connection_signature.call
|
|
|
|
@connections[ IO.new(connection.socket) ] = connection
|
|
|
|
@sockets = @connections.keys
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def run!
|
2008-09-06 16:17:06 +00:00
|
|
|
super do
|
|
|
|
catch :END_EVENT_LOOP do
|
|
|
|
loop do
|
|
|
|
result = select( @sockets,nil,nil,nil )
|
|
|
|
if result
|
|
|
|
result.first.each do |conn|
|
|
|
|
@connections[conn].get_result.each{|res| log( "Result for socket #{conn.fileno} : #{res}" ) }
|
|
|
|
@done << nil
|
|
|
|
if done?
|
|
|
|
teardown
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
2008-09-06 16:17:06 +00:00
|
|
|
end
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
protected
|
|
|
|
|
2008-09-05 23:54:48 +00:00
|
|
|
def prepare
|
|
|
|
@connections.each_value do |conn|
|
2008-09-08 16:45:00 +00:00
|
|
|
conn.send_query( "select sleep(#{@per_query_overhead})" )
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
log "done"
|
2008-09-06 16:17:06 +00:00
|
|
|
throw :END_EVENT_LOOP
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def done?
|
|
|
|
@done.size == @queries
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class ThreadedMysqlTest < MysqlTest
|
|
|
|
|
|
|
|
attr_accessor :threads
|
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
def initialize( queries, context = '' )
|
2008-09-05 23:54:48 +00:00
|
|
|
@connections = []
|
|
|
|
@threads = []
|
2008-09-08 16:45:00 +00:00
|
|
|
super( queries, context )
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def setup( &block )
|
|
|
|
super( &block )
|
|
|
|
with_logging "Setup connection pool" do
|
|
|
|
@queries.times do
|
|
|
|
@connections << @connection_signature.call
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def run!
|
2008-09-06 16:17:06 +00:00
|
|
|
super do
|
|
|
|
with_logging "waiting on threads" do
|
|
|
|
@threads.each{|t| t.join }
|
|
|
|
end
|
|
|
|
end
|
2008-09-05 23:54:48 +00:00
|
|
|
end
|
|
|
|
|
2008-09-08 16:45:00 +00:00
|
|
|
protected
|
|
|
|
|
2008-09-05 23:54:48 +00:00
|
|
|
def prepare
|
|
|
|
with_logging "prepare" do
|
|
|
|
@queries.times do |conn|
|
|
|
|
@threads << Thread.new do
|
|
|
|
|
|
|
|
log "sending query on connection #{conn}"
|
|
|
|
|
2008-09-10 00:26:01 +00:00
|
|
|
dispatch_query( @connections[conn], "select sleep(#{@per_query_overhead})", @timeout ).each do |result|
|
2008-09-05 23:54:48 +00:00
|
|
|
log "connection #{conn} done"
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|