rails_failover 0.5.9 → 0.6.0

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
  SHA256:
3
- metadata.gz: 8ecac559be38dab0f9581c922e57ac374d7725102ae643a07f15ba0a9d47dd7d
4
- data.tar.gz: a7f30fccbf59d7ab9a9f1a227725ea4f8e46b2a9aa10ddc2ac0c97ba873bcf61
3
+ metadata.gz: dea60f6f50e09e45029bc4f73d89eadefd569935d6855c3542f82aa3e1a01b3f
4
+ data.tar.gz: 5ccd925be0977242e1f139481b59a3feb3e0a4a9dbf19f8cf21064466fcdbcb4
5
5
  SHA512:
6
- metadata.gz: 268bdf1584a8082d37b4e863397439df1961a208e771ed7f600f93b78d8125c159855dc98f7655b0dbdd4d51f3e9a554c6ca36122bb3f01fb5a08d878f378680
7
- data.tar.gz: 20cc8ea824e636bb051b9f4c7fd2bd9862263592f2eca0bf21a00a24e45f3b4049acd2a0801314e79fd6be05a04a93f2fc1fbda3653a7c6852e36d04d2816a27
6
+ metadata.gz: d39ff2d6eb505dff92151c884bb7ec3aa608d4bd29c79eea2a0e2e965b8eec6ab787f930128e0d3ffcbbfb1eb2cedccf1a8fa30417eff4d3a2cfea40d536d0a7
7
+ data.tar.gz: 2b36aa85cff837f80b0876ce7b2af3017c935601ec5c5329f2bab26f5ccb395d8dd50111bee7dbf3ad2bb6e15cb22f2aa18f9fff89b3a101689f1d5036371f7e
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.0] - 2020-11-09
10
+ - FEATURE: Run failover/fallback callbacks once for each backend
11
+
12
+ Previously the failover callback would only fire when the first backend failed, and the fallback callback would only fire when the last backend recovered. Now both failover and fallback callbacks will be triggered for each backend. The key for each backend is also passed to the callbacks for consumption by consuming applications.
13
+
14
+ - FEATURE: Add primaries_down_count function to failover handlers
15
+
16
+ This is intended for consumption by monitoring systems (e.g. the Discourse prometheus exporter)
17
+
9
18
  ## [0.5.9] - 2020-11-06
10
19
  - FIX: Ignore errors from the redis socket shutdown call
11
20
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_failover (0.5.9)
4
+ rails_failover (0.6.0)
5
5
  activerecord (~> 6.0)
6
6
  railties (~> 6.0)
7
7
 
@@ -47,16 +47,20 @@ module RailsFailover
47
47
  @on_failover_callback = block
48
48
  end
49
49
 
50
- def self.on_failover_callback
51
- @on_failover_callback
50
+ def self.on_failover_callback!(key)
51
+ @on_failover_callback&.call(key)
52
+ rescue => e
53
+ logger.warn("RailsFailover::ActiveRecord.on_failover failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
52
54
  end
53
55
 
54
56
  def self.on_fallback(&block)
55
57
  @on_fallback_callback = block
56
58
  end
57
59
 
58
- def self.on_fallback_callback
59
- @on_fallback_callback
60
+ def self.on_fallback_callback!(key)
61
+ @on_fallback_callback&.call(key)
62
+ rescue => e
63
+ logger.warn("RailsFailover::ActiveRecord.on_fallback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
60
64
  end
61
65
  end
62
66
  end
@@ -18,31 +18,19 @@ module RailsFailover
18
18
  end
19
19
 
20
20
  def verify_primary(handler_key)
21
+ primary_down(handler_key)
22
+
21
23
  mon_synchronize do
22
- primary_down(handler_key)
23
24
  return if @thread&.alive?
24
25
 
25
26
  logger.warn "Failover for ActiveRecord has been initiated"
26
27
 
27
- begin
28
- RailsFailover::ActiveRecord.on_failover_callback&.call
29
- rescue => e
30
- logger.warn("RailsFailover::ActiveRecord.on_failover_callback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
31
- end
32
-
33
28
  @thread = Thread.new do
34
29
  loop do
35
30
  initiate_fallback_to_primary
36
31
 
37
32
  if all_primaries_up
38
33
  logger.warn "Fallback to primary for ActiveRecord has been completed."
39
-
40
- begin
41
- RailsFailover::ActiveRecord.on_fallback_callback&.call
42
- rescue => e
43
- logger.warn("RailsFailover::ActiveRecord.on_fallback_callback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
44
- end
45
-
46
34
  break
47
35
  end
48
36
  end
@@ -87,6 +75,12 @@ module RailsFailover
87
75
  primaries_down[handler_key]
88
76
  end
89
77
 
78
+ def primaries_down_count
79
+ mon_synchronize do
80
+ primaries_down.count
81
+ end
82
+ end
83
+
90
84
  private
91
85
 
92
86
  def all_primaries_up
@@ -96,15 +90,19 @@ module RailsFailover
96
90
  end
97
91
 
98
92
  def primary_down(handler_key)
93
+ already_down = false
99
94
  mon_synchronize do
95
+ already_down = !!primaries_down[handler_key]
100
96
  primaries_down[handler_key] = true
101
97
  end
98
+ RailsFailover::ActiveRecord.on_failover_callback!(handler_key) if !already_down
102
99
  end
103
100
 
104
101
  def primary_up(handler_key)
105
- mon_synchronize do
106
- primaries_down.delete(handler_key)
102
+ already_up = mon_synchronize do
103
+ !primaries_down.delete(handler_key)
107
104
  end
105
+ RailsFailover::ActiveRecord.on_fallback_callback!(handler_key) if !already_up
108
106
  end
109
107
 
110
108
  def spec_name
@@ -40,16 +40,20 @@ module RailsFailover
40
40
  @on_failover_callback = block
41
41
  end
42
42
 
43
- def self.on_failover_callback
44
- @on_failover_callback
43
+ def self.on_failover_callback!(key)
44
+ @on_failover_callback&.call(key)
45
+ rescue => e
46
+ logger.warn("RailsFailover::Redis.on_failover failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
45
47
  end
46
48
 
47
49
  def self.on_fallback(&block)
48
50
  @on_fallback_callback = block
49
51
  end
50
52
 
51
- def self.on_fallback_callback
52
- @on_fallback_callback
53
+ def self.on_fallback_callback!(key)
54
+ @on_fallback_callback&.call(key)
55
+ rescue => e
56
+ logger.warn("RailsFailover::Redis.on_fallback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
53
57
  end
54
58
 
55
59
  # For testing
@@ -35,12 +35,6 @@ module RailsFailover
35
35
 
36
36
  logger&.warn "Failover for Redis has been initiated"
37
37
 
38
- begin
39
- RailsFailover::Redis.on_failover_callback&.call
40
- rescue => e
41
- logger&.warn("RailsFailover::Redis.on_failover_callback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
42
- end
43
-
44
38
  @thread = Thread.new do
45
39
  loop do
46
40
  ensure_primary_clients_disconnected
@@ -48,12 +42,6 @@ module RailsFailover
48
42
 
49
43
  if all_primaries_up
50
44
  logger&.warn "Fallback to primary for Redis has been completed."
51
-
52
- begin
53
- RailsFailover::Redis.on_fallback_callback&.call
54
- rescue => e
55
- logger&.warn("RailsFailover::Redis.on_fallback_callback failed: #{e.class} #{e.message}\n#{e.backtrace.join("\n")}")
56
- end
57
45
  break
58
46
  end
59
47
  end
@@ -128,6 +116,12 @@ module RailsFailover
128
116
  end
129
117
  end
130
118
 
119
+ def primaries_down_count
120
+ mon_synchronize do
121
+ primaries_down.count
122
+ end
123
+ end
124
+
131
125
  private
132
126
 
133
127
  def all_primaries_up
@@ -135,15 +129,19 @@ module RailsFailover
135
129
  end
136
130
 
137
131
  def primary_up(options)
138
- mon_synchronize do
139
- primaries_down.delete(options[:id])
132
+ already_up = mon_synchronize do
133
+ !primaries_down.delete(options[:id])
140
134
  end
135
+ RailsFailover::Redis.on_fallback_callback!(options[:id]) if !already_up
141
136
  end
142
137
 
143
138
  def primary_down(options)
139
+ already_down = false
144
140
  mon_synchronize do
141
+ already_down = !!primaries_down[options[:id]]
145
142
  primaries_down[options[:id]] = options.dup
146
143
  end
144
+ RailsFailover::Redis.on_failover_callback!(options[:id]) if !already_down
147
145
  end
148
146
 
149
147
  def clients
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsFailover
4
- VERSION = "0.5.9"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_failover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Tan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2020-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord