lib/distribute_reads.rb in distribute_reads-0.2.0 vs lib/distribute_reads.rb in distribute_reads-0.2.1
- old
+ new
@@ -17,24 +17,42 @@
self.default_options = {
failover: true,
lag_failover: false
}
+ def self.replication_lag(connection: nil)
+ distribute_reads do
+ lag(connection: connection)
+ end
+ end
+
def self.lag(connection: nil)
raise DistributeReads::Error, "Don't use outside distribute_reads" unless Thread.current[:distribute_reads]
connection ||= ActiveRecord::Base.connection
if %w(PostgreSQL PostGIS).include?(connection.adapter_name)
replica_pool = connection.instance_variable_get(:@slave_pool)
if replica_pool && replica_pool.connections.size > 1
warn "[distribute_reads] Multiple replicas available, lag only reported for one"
end
+ # cache the version number
+ @server_version_num ||= {}
+ cache_key = connection.pool.object_id
+ @server_version_num[cache_key] ||= connection.execute("SHOW server_version_num").first["server_version_num"].to_i
+
+ lag_condition =
+ if @server_version_num[cache_key] >= 100000
+ "pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()"
+ else
+ "pg_last_xlog_receive_location() = pg_last_xlog_replay_location()"
+ end
+
connection.execute(
"SELECT CASE
- WHEN NOT pg_is_in_recovery() OR pg_last_xlog_receive_location() = pg_last_xlog_replay_location() THEN 0
+ WHEN NOT pg_is_in_recovery() OR #{lag_condition} THEN 0
ELSE EXTRACT (EPOCH FROM NOW() - pg_last_xact_replay_timestamp())
- END AS lag"
+ END AS lag".squish
).first["lag"].to_f
else
raise DistributeReads::Error, "Option not supported with this adapter"
end
end