/usr/lib/ruby/vendor_ruby/sequel/extensions/connection_validator.rb is in ruby-sequel 4.15.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # The connection_validator extension modifies a database's
# connection pool to validate that connections checked out
# from the pool are still valid, before yielding them for
# use. If it detects an invalid connection, it removes it
# from the pool and tries the next available connection,
# creating a new connection if no available connection is
# valid. Example of use:
#
# DB.extension(:connection_validator)
#
# As checking connections for validity involves issuing a
# query, which is potentially an expensive operation,
# the validation checks are only run if the connection has
# been idle for longer than a certain threshold. By default,
# that threshold is 3600 seconds (1 hour), but it can be
# modified by the user, set to -1 to always validate
# connections on checkout:
#
# DB.pool.connection_validation_timeout = -1
#
# Note that if you set the timeout to validate connections
# on every checkout, you should probably manually control
# connection checkouts on a coarse basis, using
# Database#synchronize. In a web application, the optimal
# place for that would be a rack middleware. Validating
# connections on every checkout without setting up coarse
# connection checkouts will hurt performance, in some cases
# significantly. Note that setting up coarse connection
# checkouts reduces the concurrency level acheivable. For
# example, in a web application, using Database#synchronize
# in a rack middleware will limit the number of concurrent
# web requests to the number to connections in the database
# connection pool.
#
# Note that this extension only affects the default threaded
# and the sharded threaded connection pool. The single
# threaded and sharded single threaded connection pools are
# not affected. As the only reason to use the single threaded
# pools is for speed, and this extension makes the connection
# pool slower, there's not much point in modifying this
# extension to work with the single threaded pools. The
# threaded pools work fine even in single threaded code, so if
# you are currently using a single threaded pool and want to
# use this extension, switch to using a threaded pool.
#
module Sequel
module ConnectionValidator
class Retry < Error; end
# The number of seconds that need to pass since
# connection checkin before attempting to validate
# the connection when checking it out from the pool.
# Defaults to 3600 seconds (1 hour).
attr_accessor :connection_validation_timeout
# Initialize the data structures used by this extension.
def self.extended(pool)
pool.instance_eval do
@connection_timestamps ||= {}
@connection_validation_timeout = 3600
end
# Make sure the valid connection SQL query is precached,
# otherwise it's possible it will happen at runtime. While
# it should work correctly at runtime, it's better to avoid
# the possibility of failure altogether.
pool.db.send(:valid_connection_sql)
end
private
# Record the time the connection was checked back into the pool.
def checkin_connection(*)
conn = super
@connection_timestamps[conn] = Time.now
conn
end
# When acquiring a connection, if it has been
# idle for longer than the connection validation timeout,
# test the connection for validity. If it is not valid,
# disconnect the connection, and retry with a new connection.
def acquire(*a)
begin
if (conn = super) &&
(t = sync{@connection_timestamps.delete(conn)}) &&
Time.now - t > @connection_validation_timeout &&
!db.valid_connection?(conn)
if pool_type == :sharded_threaded
sync{allocated(a.last).delete(Thread.current)}
else
sync{@allocated.delete(Thread.current)}
end
db.disconnect_connection(conn)
raise Retry
end
rescue Retry
retry
end
conn
end
end
Database.register_extension(:connection_validator){|db| db.pool.extend(ConnectionValidator)}
end
|