solid_cable 3.0.12 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2bb120f549ab39af171e93f67350d0ca6b44d2d43e42e23d538c74f894a8e4d4
4
- data.tar.gz: 13404708ae736ed703e80623b0b8496bbaca984cee263a97818951abb94fe35c
3
+ metadata.gz: 10e383ae37ea3643b84e98e513c1123340c94db2d3c0d9683c6bbd1f86f6b3dc
4
+ data.tar.gz: b883a4c70ca58c0bada49bc4ee0b42e3cac9e5c4260c42a6a2ffb2ade678ee26
5
5
  SHA512:
6
- metadata.gz: 5fc3825837aa2ee2ff4e805e40a45a2c19471576f91d0f9a0603fdb679542e2a473dd2797cd2a0bf795785ea65d713b01c2c3d0f2ef3bdcdba100608a3cf6115
7
- data.tar.gz: 1b9474761a35f8aa38063128b6c4fb3a9c30ae94b995e80d1f17eb590cf47ff84f684f557328448d8cc4aa2a26ba509b9b6c32f7ad179d140f9cc23cccca94e9
6
+ metadata.gz: c7a8924daed8e0b78e9955bad3cc800f33bb917f0fab735ea1e892af037aa51f1e5ab64fc14f363d077f3ae748e977be192d36f42c86730119e1f21729dbc508
7
+ data.tar.gz: 412baa21c8913721f097d49ceeddc9b893634c3412936fd7f8b9bfbd1d454ed5343b2677a76c785aac6ef72cf8b8edb70bae23631fcc02622a72fdd4ee3bceb0
data/README.md CHANGED
@@ -86,6 +86,8 @@ The options are:
86
86
  - `silence_polling` - whether to silence Active Record logs emitted when polling (Defaults to true)
87
87
  - `use_skip_locked` - whether to use `FOR UPDATE SKIP LOCKED` when performing trimming. This will be automatically detected in the future, and for now, you'd only need to set this to `false` if your database doesn't support it. For MySQL, that'd be versions < 8, and for PostgreSQL, versions < 9.5. If you use SQLite, this has no effect, as writes are sequential. (Defaults to true)
88
88
  - `trim_batch_size` - the batch size to use when deleting old records (default: `100`)
89
+ - `reconnect_attempts` - Supports a number of connection attempts or an array of
90
+ durations to wait between attempts. (Defaults to 1 retry attempt)
89
91
 
90
92
 
91
93
  ## Trimming
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "bundler/setup"
4
2
 
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
5
6
  require "bundler/gem_tasks"
@@ -12,6 +12,13 @@ module ActionCable
12
12
 
13
13
  def initialize(*)
14
14
  super
15
+ @mutex =
16
+ if defined?(@server)
17
+ @server.mutex
18
+ else
19
+ Mutex.new
20
+ end
21
+
15
22
  @listener = nil
16
23
  end
17
24
 
@@ -33,29 +40,52 @@ module ActionCable
33
40
 
34
41
  private
35
42
  def listener
36
- @listener || @server.mutex.synchronize do
37
- @listener ||= Listener.new(@server.event_loop)
43
+ @listener || @mutex.synchronize do
44
+ @listener ||= Listener.new(self, pubsub_executor)
38
45
  end
39
46
  end
40
47
 
48
+ def pubsub_executor
49
+ @pubsub_executor ||=
50
+ if respond_to?(:executor, true)
51
+ executor
52
+ else
53
+ @server.event_loop
54
+ end
55
+ end
56
+
41
57
  class Listener < ::ActionCable::SubscriptionAdapter::SubscriberMap
58
+ CONNECTION_ERRORS = [
59
+ ActiveRecord::ConnectionFailed,
60
+ ActiveRecord::ConnectionTimeoutError,
61
+ ActiveRecord::ConnectionNotEstablished
62
+ ]
42
63
  Stop = Class.new(Exception)
43
64
 
44
- def initialize(event_loop)
45
- super()
65
+ delegate :logger, to: :@adapter
46
66
 
47
- @event_loop = event_loop
67
+ def initialize(adapter, executor)
68
+ super()
69
+ @adapter = adapter
70
+ @executor = executor
48
71
 
49
72
  # Critical section begins with 0 permits. It can be understood as
50
73
  # being "normally held" by the listener thread. It is released
51
74
  # for specific sections of code, rather than acquired.
52
75
  @critical = Concurrent::Semaphore.new(0)
53
76
 
77
+ @reconnect_attempt = 0
78
+ @last_id = last_message_id
79
+
54
80
  @thread = Thread.new do
55
81
  Thread.current.name = "solid_cable_listener"
56
82
  Thread.current.report_on_exception = true
57
83
 
58
- listen
84
+ begin
85
+ listen
86
+ rescue *CONNECTION_ERRORS
87
+ retry if retry_connecting?
88
+ end
59
89
  end
60
90
  end
61
91
 
@@ -93,7 +123,7 @@ module ActionCable
93
123
 
94
124
  def add_channel(channel, on_success)
95
125
  channels[channel] = last_message_id
96
- event_loop.post(&on_success) if on_success
126
+ on_success.call if on_success
97
127
  end
98
128
 
99
129
  def remove_channel(channel)
@@ -101,16 +131,12 @@ module ActionCable
101
131
  end
102
132
 
103
133
  def invoke_callback(*)
104
- event_loop.post { super }
134
+ executor.post { super }
105
135
  end
106
136
 
107
137
  private
108
- attr_reader :event_loop, :thread
109
- attr_writer :last_id
110
-
111
- def last_id
112
- @last_id ||= last_message_id
113
- end
138
+ attr_reader :executor, :thread
139
+ attr_accessor :last_id, :reconnect_attempt
114
140
 
115
141
  def last_message_id
116
142
  ::SolidCable::Message.maximum(:id) || 0
@@ -135,6 +161,7 @@ module ActionCable
135
161
  end
136
162
 
137
163
  broadcast(message.channel, message.payload) if should_broadcast_message
164
+ self.reconnect_attempt = 0
138
165
  self.last_id = message.id
139
166
  end
140
167
  end
@@ -146,6 +173,22 @@ module ActionCable
146
173
  yield
147
174
  end
148
175
  end
176
+
177
+ def reconnect_attempts
178
+ @reconnect_attempts ||= ::SolidCable.reconnect_attempts
179
+ end
180
+
181
+ def retry_connecting?
182
+ self.reconnect_attempt += 1
183
+
184
+ return false if reconnect_attempt > reconnect_attempts.size
185
+
186
+ sleep_t = reconnect_attempts[reconnect_attempt - 1]
187
+
188
+ sleep(sleep_t) if sleep_t > 0
189
+
190
+ true
191
+ end
149
192
  end
150
193
  end
151
194
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidCable
4
- VERSION = "3.0.12"
4
+ VERSION = "4.0.1"
5
5
  end
data/lib/solid_cable.rb CHANGED
@@ -48,6 +48,12 @@ module SolidCable
48
48
  2
49
49
  end
50
50
 
51
+ def reconnect_attempts
52
+ attempts = cable_config.fetch(:reconnect_attempts, 1)
53
+ attempts = Array.new(attempts, 0) if attempts.is_a?(Integer)
54
+ attempts
55
+ end
56
+
51
57
  private
52
58
  def cable_config
53
59
  Rails.application.config_for("cable")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_cable
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.12
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Pezza
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '7.2'
68
+ - !ruby/object:Gem::Dependency
69
+ name: minitest
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.0'
68
82
  description: Database-backed Action Cable backend.
69
83
  email:
70
84
  - pezza@hey.com
@@ -88,7 +102,6 @@ files:
88
102
  - lib/generators/solid_cable/update/update_generator.rb
89
103
  - lib/solid_cable.rb
90
104
  - lib/solid_cable/engine.rb
91
- - lib/solid_cable/railtie.rb
92
105
  - lib/solid_cable/version.rb
93
106
  - lib/tasks/solid_cable_tasks.rake
94
107
  homepage: https://github.com/rails/solid_cable
@@ -105,14 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
118
  requirements:
106
119
  - - ">="
107
120
  - !ruby/object:Gem::Version
108
- version: 3.1.0
121
+ version: 3.3.0
109
122
  required_rubygems_version: !ruby/object:Gem::Requirement
110
123
  requirements:
111
124
  - - ">="
112
125
  - !ruby/object:Gem::Version
113
126
  version: '0'
114
127
  requirements: []
115
- rubygems_version: 3.6.9
128
+ rubygems_version: 4.0.15
116
129
  specification_version: 4
117
130
  summary: Database-backed Action Cable backend.
118
131
  test_files: []
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidCable
4
- class Railtie < ::Rails::Railtie
5
- end
6
- end