distribute_reads 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6f3a694f47520a9cf55b522c9a2acf4ec54be50
4
- data.tar.gz: 20d1d2439e24112ac8d165ad79623edc65222f9d
3
+ metadata.gz: db257dfd9b8679aad4cc3d4ee162234ee7375fda
4
+ data.tar.gz: 87daf348a55b8b11e17aa6fcdb181f0233b59569
5
5
  SHA512:
6
- metadata.gz: 5434b9aa41816fed52ed2cb9f4f18445b4d5242b9f8f78ad40830e00981ffa2cd46dad8fbe8e4e77f3b98716624075b4e0854bb99d19554fa07492c5f9c90b31
7
- data.tar.gz: 7d4116b3c7a8c17a96cf6838fbf29f16a89454162a699786b73dba5e64475d757c749143f12b0275fef333329474db60e822343908e8fda4f34f51af8896d4d3
6
+ metadata.gz: 86bd0d6b2be128b6bc20b0b6ff0eb455b7eba40f33db2d12437326f13bc60c1400ed6d3f871c84a1dd9fe97ffc5122aa4b3a93291e9c1dde8d3e4dd3814a86cc
7
+ data.tar.gz: 937a288f831c21fa91546ad6ad89d4a84ea239edf6739a6936540a19cc3a0ec1d9fe19aeefea3e57ffce77d32c50bb536f9309b038c749d17fa9497976eae551
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.2.2
2
+
3
+ - Added support for MySQL replication lag
4
+ - Added `replica` option
5
+
1
6
  ## 0.2.1
2
7
 
3
8
  - Fixed lag check for Postgres 10
data/README.md CHANGED
@@ -76,7 +76,7 @@ You can pass any options as well.
76
76
 
77
77
  ### Replica Lag
78
78
 
79
- Raise an error when replica lag is too high - *PostgreSQL only*
79
+ Raise an error when replica lag is too high
80
80
 
81
81
  ```ruby
82
82
  distribute_reads(max_lag: 3) do
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "bundler"
26
26
  spec.add_development_dependency "rake"
27
27
  spec.add_development_dependency "minitest"
28
- spec.add_development_dependency "pg"
28
+ spec.add_development_dependency "pg", "< 1"
29
+ spec.add_development_dependency "mysql2"
29
30
  spec.add_development_dependency "activejob"
30
31
  end
@@ -29,12 +29,13 @@ module DistributeReads
29
29
  raise DistributeReads::Error, "Don't use outside distribute_reads" unless Thread.current[:distribute_reads]
30
30
 
31
31
  connection ||= ActiveRecord::Base.connection
32
- if %w(PostgreSQL PostGIS).include?(connection.adapter_name)
33
- replica_pool = connection.instance_variable_get(:@slave_pool)
34
- if replica_pool && replica_pool.connections.size > 1
35
- warn "[distribute_reads] Multiple replicas available, lag only reported for one"
36
- end
37
32
 
33
+ replica_pool = connection.instance_variable_get(:@slave_pool)
34
+ if replica_pool && replica_pool.connections.size > 1
35
+ warn "[distribute_reads] Multiple replicas available, lag only reported for one"
36
+ end
37
+
38
+ if %w(PostgreSQL PostGIS).include?(connection.adapter_name)
38
39
  # cache the version number
39
40
  @server_version_num ||= {}
40
41
  cache_key = connection.pool.object_id
@@ -53,6 +54,16 @@ module DistributeReads
53
54
  ELSE EXTRACT (EPOCH FROM NOW() - pg_last_xact_replay_timestamp())
54
55
  END AS lag".squish
55
56
  ).first["lag"].to_f
57
+ elsif %w(MySQL Mysql2 Mysql2Spatial Mysql2Rgeo).include?(connection.adapter_name)
58
+ replica_value = Thread.current[:distribute_reads][:replica]
59
+ begin
60
+ # makara doesn't send SHOW queries to replica, so we must force it
61
+ Thread.current[:distribute_reads][:replica] = true
62
+ status = connection.exec_query("SHOW SLAVE STATUS").to_hash.first
63
+ status ? status["Seconds_Behind_Master"].to_f : 0.0
64
+ ensure
65
+ Thread.current[:distribute_reads][:replica] = replica_value
66
+ end
56
67
  else
57
68
  raise DistributeReads::Error, "Option not supported with this adapter"
58
69
  end
@@ -2,7 +2,14 @@ module DistributeReads
2
2
  module AppropriatePool
3
3
  def _appropriate_pool(*args)
4
4
  if Thread.current[:distribute_reads]
5
- if Thread.current[:distribute_reads][:primary] || needs_master?(*args) || (blacklisted = @slave_pool.completely_blacklisted?)
5
+ if Thread.current[:distribute_reads][:replica]
6
+ if @slave_pool.completely_blacklisted?
7
+ raise DistributeReads::NoReplicasAvailable, "No replicas available" if Thread.current[:distribute_reads][:failover] == false
8
+ @master_pool
9
+ else
10
+ @slave_pool
11
+ end
12
+ elsif Thread.current[:distribute_reads][:primary] || needs_master?(*args) || (blacklisted = @slave_pool.completely_blacklisted?)
6
13
  raise DistributeReads::NoReplicasAvailable, "No replicas available" if blacklisted && Thread.current[:distribute_reads][:failover] == false
7
14
  stick_to_master(*args) if DistributeReads.by_default
8
15
  @master_pool
@@ -3,14 +3,18 @@ module DistributeReads
3
3
  def distribute_reads(**options)
4
4
  raise ArgumentError, "Missing block" unless block_given?
5
5
 
6
- unknown_keywords = options.keys - [:failover, :lag_failover, :lag_on, :max_lag, :primary]
6
+ unknown_keywords = options.keys - [:failover, :lag_failover, :lag_on, :max_lag, :primary, :replica]
7
7
  raise ArgumentError, "Unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
8
8
 
9
9
  options = DistributeReads.default_options.merge(options)
10
10
 
11
11
  previous_value = Thread.current[:distribute_reads]
12
12
  begin
13
- Thread.current[:distribute_reads] = {failover: options[:failover], primary: options[:primary]}
13
+ Thread.current[:distribute_reads] = {
14
+ failover: options[:failover],
15
+ primary: options[:primary],
16
+ replica: options[:replica]
17
+ }
14
18
 
15
19
  # TODO ensure same connection is used to test lag and execute queries
16
20
  max_lag = options[:max_lag]
@@ -20,6 +24,8 @@ module DistributeReads
20
24
  if options[:lag_failover]
21
25
  # TODO possibly per connection
22
26
  Thread.current[:distribute_reads][:primary] = true
27
+ Thread.current[:distribute_reads][:replica] = false
28
+ break
23
29
  else
24
30
  raise DistributeReads::TooMuchLag, "Replica lag over #{max_lag} seconds#{options[:lag_on] ? " on #{base_model.name} connection" : ""}"
25
31
  end
@@ -1,3 +1,3 @@
1
1
  module DistributeReads
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distribute_reads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-15 00:00:00.000000000 Z
11
+ date: 2018-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: makara
@@ -68,6 +68,20 @@ dependencies:
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pg
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "<"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mysql2
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="