连接不会引发错误主机
Connection won't raise error with bad host
我正在开发的应用程序允许用户通过 UI 添加到其他数据库的额外连接。我只是想创建一个确保可以建立连接的验证。
我创建了一个单独的 class 来测试数据库连接:
class StoredProcConnection < ActiveRecord::Base
def self.abstract_class?
true # So it gets its own connection
end
end
然后我创建连接:
def connect
adapter = sql_server? ? 'mssql' : 'mysql2'
default_port = sql_server? ? '1443' : '3306'
@connection_pool = StoredProcConnection.establish_connection(
adapter: adapter,
username: username,
password: password,
host: host,
database: database_name,
port: port || default_port,
timeout: 300)
end
def connection_pool
connect unless @connection_pool
@connection_pool
end
然后我用这个方法验证一下:
def connection_test
if connection_pool.connection
#remove the connection from the StoredProcConnection pool
connection_pool.remove(connection_pool.connection)
return true
else
return false
end
rescue Exception => error
logger.info "unable to create connection with connection.id = #{id} - #{error}"
return false
end
不幸的是,当它到达带有错误主机地址的这一行时,如 127.0.0.abcdefg
或 666.666.666.666
if connection_pool.connect
应用程序卡住了,没有出现任何错误。它只是冻结,我必须手动关闭服务器。
我有一个解决方法,但感觉很草率。我只是在那里插入我自己的超时,但我觉得 Active Record 应该抛出某种错误。
def connection_test
Timeout::timeout(3) {
if connection_pool.connection
#remove the connection from the StoredProcConnection pool
connection_pool.remove(connection_pool.connection)
return true
else
return false
end
}
rescue Exception => error
logger.info "unable to create connection with connection.id = #{id} - #{error}"
return false
end
有没有人看到任何可能导致冻结的原因?这对我来说似乎很简单。我不确定为什么在传入错误主机的情况下甚至首先创建连接池。
It just freezes...
很有可能它没有被冻结,它只是在等着看是否可以建立连接。 TCP/IP 有一个很长的超时值,它使人们误以为事情已经冻结,而实际上它是在耐心等待。
很少有人真正了解互联网是如何运作的,以及它是如何真正成为我们无论如何都试图保留 运行 的稻草屋。长 IP 超时是我们尝试使其自我修复的方法之一。软件不关心需要多长时间,只有人在乎。
既然您担心 IP 地址格式不正确,为什么不预先测试它们以确保它们至少采用有效格式?
使用 Ruby 的内置 IPAddr class 并尝试解析它们:
require 'ipaddr'
%w[
127.0.0.abcdefg
666.666.666.666
127.0.0.1
192.168.0.1
255.255.255.255
].each do |ip|
begin
IPAddr.new ip
puts "Good: #{ ip }"
rescue IPAddr::InvalidAddressError => e
puts "#{ e }: #{ ip }"
end
end
# >> invalid address: 127.0.0.abcdefg
# >> invalid address: 666.666.666.666
# >> Good: 127.0.0.1
# >> Good: 192.168.0.1
# >> Good: 255.255.255.255
"fun reading" 有“TCP Timeout and Retransmission" and "TCP Socket no connection timeout”。
我正在开发的应用程序允许用户通过 UI 添加到其他数据库的额外连接。我只是想创建一个确保可以建立连接的验证。 我创建了一个单独的 class 来测试数据库连接:
class StoredProcConnection < ActiveRecord::Base
def self.abstract_class?
true # So it gets its own connection
end
end
然后我创建连接:
def connect
adapter = sql_server? ? 'mssql' : 'mysql2'
default_port = sql_server? ? '1443' : '3306'
@connection_pool = StoredProcConnection.establish_connection(
adapter: adapter,
username: username,
password: password,
host: host,
database: database_name,
port: port || default_port,
timeout: 300)
end
def connection_pool
connect unless @connection_pool
@connection_pool
end
然后我用这个方法验证一下:
def connection_test
if connection_pool.connection
#remove the connection from the StoredProcConnection pool
connection_pool.remove(connection_pool.connection)
return true
else
return false
end
rescue Exception => error
logger.info "unable to create connection with connection.id = #{id} - #{error}"
return false
end
不幸的是,当它到达带有错误主机地址的这一行时,如 127.0.0.abcdefg
或 666.666.666.666
if connection_pool.connect
应用程序卡住了,没有出现任何错误。它只是冻结,我必须手动关闭服务器。
我有一个解决方法,但感觉很草率。我只是在那里插入我自己的超时,但我觉得 Active Record 应该抛出某种错误。
def connection_test
Timeout::timeout(3) {
if connection_pool.connection
#remove the connection from the StoredProcConnection pool
connection_pool.remove(connection_pool.connection)
return true
else
return false
end
}
rescue Exception => error
logger.info "unable to create connection with connection.id = #{id} - #{error}"
return false
end
有没有人看到任何可能导致冻结的原因?这对我来说似乎很简单。我不确定为什么在传入错误主机的情况下甚至首先创建连接池。
It just freezes...
很有可能它没有被冻结,它只是在等着看是否可以建立连接。 TCP/IP 有一个很长的超时值,它使人们误以为事情已经冻结,而实际上它是在耐心等待。
很少有人真正了解互联网是如何运作的,以及它是如何真正成为我们无论如何都试图保留 运行 的稻草屋。长 IP 超时是我们尝试使其自我修复的方法之一。软件不关心需要多长时间,只有人在乎。
既然您担心 IP 地址格式不正确,为什么不预先测试它们以确保它们至少采用有效格式?
使用 Ruby 的内置 IPAddr class 并尝试解析它们:
require 'ipaddr'
%w[
127.0.0.abcdefg
666.666.666.666
127.0.0.1
192.168.0.1
255.255.255.255
].each do |ip|
begin
IPAddr.new ip
puts "Good: #{ ip }"
rescue IPAddr::InvalidAddressError => e
puts "#{ e }: #{ ip }"
end
end
# >> invalid address: 127.0.0.abcdefg
# >> invalid address: 666.666.666.666
# >> Good: 127.0.0.1
# >> Good: 192.168.0.1
# >> Good: 255.255.255.255
"fun reading" 有“TCP Timeout and Retransmission" and "TCP Socket no connection timeout”。