-
Notifications
You must be signed in to change notification settings - Fork 15
Open
Description
after modifying io_reactor.rb by adding the following on line 136:
rescue => e
puts "#{e.class.name}: #{e.message}\n" + Array(e.backtrace).join("\n")I get the following error:
TypeError: can't convert Ione::Io::Connection to IO (Ione::Io::Connection#to_io gives NilClass)
/home/kishan/.rvm/gems/ruby-1.9.3-p547@global/gems/ione-1.2.0/lib/ione/io/io_reactor.rb:396:in `select'
/home/kishan/.rvm/gems/ruby-1.9.3-p547@global/gems/ione-1.2.0/lib/ione/io/io_reactor.rb:396:in `tick'
/home/kishan/.rvm/gems/ruby-1.9.3-p547@global/gems/ione-1.2.0/lib/ione/io/io_reactor.rb:133:in `block in start'
integration/test.rb:38:in `join': deadlock detected (fatal)
from integration/test.rb:38:in `block in create_sessions_concurrently2'
from integration/test.rb:38:in `each'
from integration/test.rb:38:in `create_sessions_concurrently2'
from integration/test.rb:15:in `run_test'
from integration/test.rb:61:in `<main>'
The issue is that the connections are created and closed from different threads, here is a trimmed down sample that consistently fails on linux, while passing on OS X:
require 'bundler/setup'
require 'cassandra'
require 'cassandra/version'
puts Cassandra::VERSION
class Test
def run_test
cluster_list = []
cluster_list << Cassandra.cluster
session_list = create_sessions_concurrently2(cluster_list[0], 1)
p session_list
session_list = close_sessions_concurrently2(session_list, 1)
p session_list
session_list2 = create_sessions_concurrently2(cluster_list[0], 1) # DEADLOCK HERE
p session_list2
session_list = close_sessions_concurrently2(session_list2, 1)
p session_list
cluster_list[0].close
end
def create_sessions_concurrently2(cluster, num_sessions)
sessions = []
threads = (1..num_sessions).map do
Thread.new do
begin
session = cluster.connect
sessions << session
rescue Exception => e
# session.close
raise RuntimeError.new("Error while creating a session. #{e.class.name}: #{e.message}
Backtrace: #{e.backtrace.inspect}")
end
end
end
threads.each {|th| th.join} # DEADLOCK HERE
sessions
end
def close_sessions_concurrently2(session_list, num_sessions)
session_list2 = session_list[0...num_sessions]
threads = session_list2.map do |session|
Thread.new do
begin
session.close
session_list.delete(session)
rescue Exception => e
raise RuntimeError.new("Error while closing a session. #{e.class.name}: #{e.message}
Backtrace: #{e.backtrace.inspect}")
end
end
end
threads.each {|th| th.join}
session_list
end
end
Test.new.run_testI believe there is a race between close and connected? that causes a closing socket to be added to the poll list.
Metadata
Metadata
Assignees
Labels
No labels