anycable-rails 1.4.0 → 1.4.2
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 +4 -4
- data/CHANGELOG.md +18 -0
- metadata +10 -58
- data/lib/action_cable/subscription_adapter/any_cable.rb +0 -40
- data/lib/action_cable/subscription_adapter/anycable.rb +0 -10
- data/lib/anycable/rails/action_cable_ext/channel.rb +0 -51
- data/lib/anycable/rails/action_cable_ext/connection.rb +0 -90
- data/lib/anycable/rails/action_cable_ext/remote_connections.rb +0 -13
- data/lib/anycable/rails/channel_state.rb +0 -108
- data/lib/anycable/rails/compatibility/rubocop/config/default.yml +0 -14
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb +0 -50
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb +0 -29
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb +0 -100
- data/lib/anycable/rails/compatibility/rubocop.rb +0 -27
- data/lib/anycable/rails/compatibility.rb +0 -63
- data/lib/anycable/rails/config.rb +0 -19
- data/lib/anycable/rails/connection.rb +0 -211
- data/lib/anycable/rails/connection_factory.rb +0 -44
- data/lib/anycable/rails/connections/persistent_session.rb +0 -40
- data/lib/anycable/rails/connections/serializable_identification.rb +0 -46
- data/lib/anycable/rails/connections/session_proxy.rb +0 -81
- data/lib/anycable/rails/middlewares/executor.rb +0 -31
- data/lib/anycable/rails/middlewares/log_tagging.rb +0 -21
- data/lib/anycable/rails/rack.rb +0 -56
- data/lib/anycable/rails/railtie.rb +0 -92
- data/lib/anycable/rails/version.rb +0 -7
- data/lib/anycable/rails.rb +0 -76
- data/lib/anycable-rails.rb +0 -3
- data/lib/generators/anycable/download/USAGE +0 -14
- data/lib/generators/anycable/download/download_generator.rb +0 -85
- data/lib/generators/anycable/setup/USAGE +0 -2
- data/lib/generators/anycable/setup/setup_generator.rb +0 -300
- data/lib/generators/anycable/setup/templates/Procfile.dev.tt +0 -6
- data/lib/generators/anycable/setup/templates/config/anycable.yml.tt +0 -48
- data/lib/generators/anycable/setup/templates/config/cable.yml.tt +0 -11
- data/lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt +0 -9
- data/lib/generators/anycable/with_os_helpers.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9be01ceeb56d7e9c614212631608fe5bf344dcb383f94d87265d2f78c2d765b
|
4
|
+
data.tar.gz: 7d6224ccaad49d71ead36ad452028a9bfa2671a50fa7d88a6e6aecda8bf6dc95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9880ec9c148ac54ba58f72d2b4a104c51101a47c3af99abfbbb359716ccb3a2ada229d7dec634806d1eaea68da44c017c3ca33899bdbeb2a738caaf39014ed03
|
7
|
+
data.tar.gz: f5e775c99020c9b2f3297b6ad3fb7a18f1d9de73ca6b500c6ef7ccac4b854796d12101b3c210c2b0154634f128a413dcd2a5db106066878a00a98c864071f702
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.4.2 (2023-10-15)
|
6
|
+
|
7
|
+
- Print warning if the database pool size is less than RPC pool size. ([@palkan][])
|
8
|
+
|
9
|
+
- Add support for broadcast options (e.g., `exclude_socket`) and `broadcast ..., to_others: true`. ([@palkan][])
|
10
|
+
|
11
|
+
- Add `batch_broadcasts` option to automatically batch broadcasts for code wrapped in Rails executor. ([@palkan][])
|
12
|
+
|
13
|
+
- Fix broadcast logging in Rails 7.1. ([@iuri-gg][])
|
14
|
+
|
15
|
+
## 1.4.1 (2023-09-27)
|
16
|
+
|
17
|
+
- Fix compatibility with Rails 7.1. ([@palkan][])
|
18
|
+
|
19
|
+
- Upgrade `anycable:setup` generator to support v1.4 features. ([@palkan][])
|
20
|
+
|
21
|
+
Add `bin/anycable-go` to use `anycable-go` locally. Add `--rpc=http` to configure for using AnyCable with HTTP RPC.
|
22
|
+
|
5
23
|
## 1.4.0 (2023-07-07)
|
6
24
|
|
7
25
|
- Add HTTP RPC integration. ([@palkan][])
|
metadata
CHANGED
@@ -1,45 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: anycable
|
14
|
+
name: anycable-rails-core
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.4.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.4.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '6.0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '6.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: globalid
|
28
|
+
name: anycable
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -164,7 +150,7 @@ dependencies:
|
|
164
150
|
- - ">="
|
165
151
|
- !ruby/object:Gem::Version
|
166
152
|
version: '0'
|
167
|
-
description:
|
153
|
+
description: AnyCable integration for Rails
|
168
154
|
email:
|
169
155
|
- dementiev.vm@gmail.com
|
170
156
|
executables: []
|
@@ -174,40 +160,6 @@ files:
|
|
174
160
|
- CHANGELOG.md
|
175
161
|
- MIT-LICENSE
|
176
162
|
- README.md
|
177
|
-
- lib/action_cable/subscription_adapter/any_cable.rb
|
178
|
-
- lib/action_cable/subscription_adapter/anycable.rb
|
179
|
-
- lib/anycable-rails.rb
|
180
|
-
- lib/anycable/rails.rb
|
181
|
-
- lib/anycable/rails/action_cable_ext/channel.rb
|
182
|
-
- lib/anycable/rails/action_cable_ext/connection.rb
|
183
|
-
- lib/anycable/rails/action_cable_ext/remote_connections.rb
|
184
|
-
- lib/anycable/rails/channel_state.rb
|
185
|
-
- lib/anycable/rails/compatibility.rb
|
186
|
-
- lib/anycable/rails/compatibility/rubocop.rb
|
187
|
-
- lib/anycable/rails/compatibility/rubocop/config/default.yml
|
188
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb
|
189
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb
|
190
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb
|
191
|
-
- lib/anycable/rails/config.rb
|
192
|
-
- lib/anycable/rails/connection.rb
|
193
|
-
- lib/anycable/rails/connection_factory.rb
|
194
|
-
- lib/anycable/rails/connections/persistent_session.rb
|
195
|
-
- lib/anycable/rails/connections/serializable_identification.rb
|
196
|
-
- lib/anycable/rails/connections/session_proxy.rb
|
197
|
-
- lib/anycable/rails/middlewares/executor.rb
|
198
|
-
- lib/anycable/rails/middlewares/log_tagging.rb
|
199
|
-
- lib/anycable/rails/rack.rb
|
200
|
-
- lib/anycable/rails/railtie.rb
|
201
|
-
- lib/anycable/rails/version.rb
|
202
|
-
- lib/generators/anycable/download/USAGE
|
203
|
-
- lib/generators/anycable/download/download_generator.rb
|
204
|
-
- lib/generators/anycable/setup/USAGE
|
205
|
-
- lib/generators/anycable/setup/setup_generator.rb
|
206
|
-
- lib/generators/anycable/setup/templates/Procfile.dev.tt
|
207
|
-
- lib/generators/anycable/setup/templates/config/anycable.yml.tt
|
208
|
-
- lib/generators/anycable/setup/templates/config/cable.yml.tt
|
209
|
-
- lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt
|
210
|
-
- lib/generators/anycable/with_os_helpers.rb
|
211
163
|
homepage: http://github.com/anycable/anycable-rails
|
212
164
|
licenses:
|
213
165
|
- MIT
|
@@ -236,5 +188,5 @@ requirements: []
|
|
236
188
|
rubygems_version: 3.4.8
|
237
189
|
signing_key:
|
238
190
|
specification_version: 4
|
239
|
-
summary:
|
191
|
+
summary: AnyCable integration for Rails
|
240
192
|
test_files: []
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "anycable-rails"
|
4
|
-
|
5
|
-
module ActionCable
|
6
|
-
module SubscriptionAdapter
|
7
|
-
# AnyCable subscription adapter delegates broadcasts
|
8
|
-
# to AnyCable
|
9
|
-
class AnyCable < Base
|
10
|
-
ACTION_CABLE_SERVER_ERROR_MESSAGE = <<~STR
|
11
|
-
Looks like you're trying to connect to Rails Action Cable server, not an AnyCable one.
|
12
|
-
|
13
|
-
Please make sure your client is configured to connect to AnyCable server.
|
14
|
-
|
15
|
-
See https://docs.anycable.io/troubleshooting
|
16
|
-
STR
|
17
|
-
|
18
|
-
def initialize(*)
|
19
|
-
end
|
20
|
-
|
21
|
-
def broadcast(channel, payload)
|
22
|
-
::AnyCable.broadcast(channel, payload)
|
23
|
-
end
|
24
|
-
|
25
|
-
def subscribe(*)
|
26
|
-
raise NotImplementedError, ACTION_CABLE_SERVER_ERROR_MESSAGE
|
27
|
-
end
|
28
|
-
|
29
|
-
def unsubscribe(*)
|
30
|
-
raise NotImplementedError, ACTION_CABLE_SERVER_ERROR_MESSAGE
|
31
|
-
end
|
32
|
-
|
33
|
-
def shutdown
|
34
|
-
# nothing to do
|
35
|
-
# we only need this method for development,
|
36
|
-
# 'cause code reloading triggers `server.restart` -> `pubsub.shutdown`
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "action_cable"
|
4
|
-
|
5
|
-
ActionCable::Channel::Base.prepend(Module.new do
|
6
|
-
def subscribe_to_channel
|
7
|
-
super unless anycabled? && !@__anycable_subscribing__
|
8
|
-
end
|
9
|
-
|
10
|
-
def handle_subscribe
|
11
|
-
@__anycable_subscribing__ = true
|
12
|
-
subscribe_to_channel
|
13
|
-
ensure
|
14
|
-
@__anycable_subscribing__ = false
|
15
|
-
end
|
16
|
-
|
17
|
-
def start_periodic_timers
|
18
|
-
super unless anycabled?
|
19
|
-
end
|
20
|
-
|
21
|
-
def stop_periodic_timers
|
22
|
-
super unless anycabled?
|
23
|
-
end
|
24
|
-
|
25
|
-
def stream_from(broadcasting, _callback = nil, **)
|
26
|
-
return super unless anycabled?
|
27
|
-
|
28
|
-
broadcasting = String(broadcasting)
|
29
|
-
|
30
|
-
connection.anycable_socket.subscribe identifier, broadcasting
|
31
|
-
end
|
32
|
-
|
33
|
-
def stop_stream_from(broadcasting)
|
34
|
-
return super unless anycabled?
|
35
|
-
|
36
|
-
connection.anycable_socket.unsubscribe identifier, broadcasting
|
37
|
-
end
|
38
|
-
|
39
|
-
def stop_all_streams
|
40
|
-
return super unless anycabled?
|
41
|
-
|
42
|
-
connection.anycable_socket.unsubscribe_from_all identifier
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def anycabled?
|
48
|
-
# Use instance variable check here for testing compatibility
|
49
|
-
connection.instance_variable_defined?(:@anycable_socket)
|
50
|
-
end
|
51
|
-
end)
|
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "action_cable"
|
4
|
-
require "anycable/rails/connections/serializable_identification"
|
5
|
-
|
6
|
-
ActionCable::Connection::Base.include(AnyCable::Rails::Connections::SerializableIdentification)
|
7
|
-
ActionCable::Connection::Base.prepend(Module.new do
|
8
|
-
attr_reader :anycable_socket
|
9
|
-
attr_accessor :anycable_request_builder
|
10
|
-
|
11
|
-
# In AnyCable, we lazily populate env by passing it through the middleware chain,
|
12
|
-
# so we access it via #request
|
13
|
-
def env
|
14
|
-
return super unless anycabled?
|
15
|
-
|
16
|
-
request.env
|
17
|
-
end
|
18
|
-
|
19
|
-
def anycabled?
|
20
|
-
@anycable_socket
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def request
|
26
|
-
return super unless anycabled?
|
27
|
-
|
28
|
-
@request ||= anycable_request_builder.build_rack_request(@env)
|
29
|
-
end
|
30
|
-
end)
|
31
|
-
|
32
|
-
# Backport command callbacks: https://github.com/rails/rails/pull/44696
|
33
|
-
unless ActionCable::Connection::Base.respond_to?(:before_command)
|
34
|
-
ActionCable::Connection::Base.include ActiveSupport::Callbacks
|
35
|
-
ActionCable::Connection::Base.define_callbacks :command
|
36
|
-
ActionCable::Connection::Base.extend(Module.new do
|
37
|
-
def before_command(*methods, &block)
|
38
|
-
set_callback(:command, :before, *methods, &block)
|
39
|
-
end
|
40
|
-
|
41
|
-
def after_command(*methods, &block)
|
42
|
-
set_callback(:command, :after, *methods, &block)
|
43
|
-
end
|
44
|
-
|
45
|
-
def around_command(*methods, &block)
|
46
|
-
set_callback(:command, :around, *methods, &block)
|
47
|
-
end
|
48
|
-
end)
|
49
|
-
|
50
|
-
ActionCable::Connection::Base.prepend(Module.new do
|
51
|
-
def dispatch_websocket_message(websocket_message)
|
52
|
-
return super unless websocket.alive?
|
53
|
-
|
54
|
-
handle_channel_command(decode(websocket_message))
|
55
|
-
end
|
56
|
-
|
57
|
-
def handle_channel_command(payload)
|
58
|
-
run_callbacks :command do
|
59
|
-
subscriptions.execute_command payload
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Trigger autoload
|
66
|
-
test_case_defined = false
|
67
|
-
|
68
|
-
begin
|
69
|
-
ActionCable::Connection::TestCase # rubocop:disable Lint/Void
|
70
|
-
test_case_defined = true
|
71
|
-
rescue NameError
|
72
|
-
end
|
73
|
-
|
74
|
-
# Backport: https://github.com/rails/rails/pull/45445
|
75
|
-
if test_case_defined && !ActionCable::Connection::TestConnection.method_defined?(:transmissions)
|
76
|
-
ActionCable::Connection::TestConnection.prepend(Module.new do
|
77
|
-
attr_reader :transmissions
|
78
|
-
|
79
|
-
def initialize(*)
|
80
|
-
super
|
81
|
-
|
82
|
-
@transmissions = []
|
83
|
-
@subscriptions = ActionCable::Connection::Subscriptions.new(self)
|
84
|
-
end
|
85
|
-
|
86
|
-
def transmit(cable_message)
|
87
|
-
transmissions << cable_message.with_indifferent_access
|
88
|
-
end
|
89
|
-
end)
|
90
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "action_cable/remote_connections"
|
4
|
-
|
5
|
-
ActionCable::RemoteConnections::RemoteConnection.include(AnyCable::Rails::Connections::SerializableIdentification)
|
6
|
-
|
7
|
-
ActionCable::RemoteConnections::RemoteConnection.prepend(Module.new do
|
8
|
-
def disconnect(reconnect: true)
|
9
|
-
# Legacy Action Cable functionality if case we're not fully migrated yet
|
10
|
-
super() unless AnyCable::Rails.enabled?
|
11
|
-
::AnyCable.broadcast_adapter.broadcast_command("disconnect", identifier: identifiers_json, reconnect: reconnect)
|
12
|
-
end
|
13
|
-
end)
|
@@ -1,108 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AnyCable
|
4
|
-
module Rails
|
5
|
-
module ChannelState
|
6
|
-
module ClassMethods
|
7
|
-
def state_attr_accessor(*names)
|
8
|
-
names.each do |name|
|
9
|
-
channel_state_attributes << name
|
10
|
-
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
11
|
-
def #{name}
|
12
|
-
return @#{name} if instance_variable_defined?(:@#{name})
|
13
|
-
@#{name} = AnyCable::Rails.deserialize(__istate__["#{name}"], json: true) if anycabled?
|
14
|
-
end
|
15
|
-
|
16
|
-
def #{name}=(val)
|
17
|
-
__istate__["#{name}"] = AnyCable::Rails.serialize(val, json: true) if anycabled?
|
18
|
-
instance_variable_set(:@#{name}, val)
|
19
|
-
end
|
20
|
-
RUBY
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def channel_state_attributes
|
25
|
-
return @channel_state_attributes if instance_variable_defined?(:@channel_state_attributes)
|
26
|
-
|
27
|
-
@channel_state_attributes =
|
28
|
-
if superclass.respond_to?(:channel_state_attributes)
|
29
|
-
superclass.channel_state_attributes.dup
|
30
|
-
else
|
31
|
-
[]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.included(base)
|
37
|
-
base.extend ClassMethods
|
38
|
-
end
|
39
|
-
|
40
|
-
# Make it possible to provide istate explicitly for a channel instance
|
41
|
-
attr_writer :__istate__
|
42
|
-
|
43
|
-
def __istate__
|
44
|
-
@__istate__ ||= connection.anycable_socket.istate
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
module ConnectionState
|
49
|
-
module ClassMethods
|
50
|
-
def state_attr_accessor(*names)
|
51
|
-
names.each do |name|
|
52
|
-
connection_state_attributes << name
|
53
|
-
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
54
|
-
def #{name}
|
55
|
-
return @#{name} if instance_variable_defined?(:@#{name})
|
56
|
-
@#{name} = AnyCable::Rails.deserialize(__cstate__["#{name}"], json: true) if anycabled?
|
57
|
-
end
|
58
|
-
|
59
|
-
def #{name}=(val)
|
60
|
-
__cstate__["#{name}"] = AnyCable::Rails.serialize(val, json: true) if anycabled?
|
61
|
-
instance_variable_set(:@#{name}, val)
|
62
|
-
end
|
63
|
-
RUBY
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def connection_state_attributes
|
68
|
-
return @connection_state_attributes if instance_variable_defined?(:@connection_state_attributes)
|
69
|
-
|
70
|
-
@connection_state_attributes =
|
71
|
-
if superclass.respond_to?(:connection_state_attributes)
|
72
|
-
superclass.connection_state_attributes.dup
|
73
|
-
else
|
74
|
-
[]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.included(base)
|
80
|
-
base.extend ClassMethods
|
81
|
-
end
|
82
|
-
|
83
|
-
# Make it possible to provide istate explicitly for a connection instance
|
84
|
-
attr_writer :__cstate__
|
85
|
-
|
86
|
-
def __cstate__
|
87
|
-
@__cstate__ ||= anycable_socket.cstate
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if ActiveSupport::VERSION::MAJOR < 6
|
94
|
-
# `state_attr_accessor` must be available in Action Cable
|
95
|
-
ActiveSupport.on_load(:action_cable) do
|
96
|
-
::ActionCable::Connection::Base.include(AnyCable::Rails::ConnectionState)
|
97
|
-
::ActionCable::Channel::Base.include(AnyCable::Rails::ChannelState)
|
98
|
-
end
|
99
|
-
else
|
100
|
-
# `state_attr_accessor` must be available in Action Cable
|
101
|
-
ActiveSupport.on_load(:action_cable_connection) do
|
102
|
-
::ActionCable::Connection::Base.include(AnyCable::Rails::ConnectionState)
|
103
|
-
end
|
104
|
-
|
105
|
-
ActiveSupport.on_load(:action_cable_channel) do
|
106
|
-
::ActionCable::Channel::Base.include(AnyCable::Rails::ChannelState)
|
107
|
-
end
|
108
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module AnyCable
|
8
|
-
# Checks for instance variable usage inside subscriptions.
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# class MyChannel < ApplicationCable::Channel
|
13
|
-
# def subscribed
|
14
|
-
# @post = Post.find(params[:id])
|
15
|
-
# stream_from @post
|
16
|
-
# end
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# # good
|
20
|
-
# class MyChannel < ApplicationCable::Channel
|
21
|
-
# def subscribed
|
22
|
-
# post = Post.find(params[:id])
|
23
|
-
# stream_from post
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
class InstanceVars < RuboCop::Cop::Cop
|
28
|
-
MSG = "Channel instance variables are not supported in AnyCable. Use `state_attr_accessor` instead"
|
29
|
-
|
30
|
-
def on_class(node)
|
31
|
-
find_nested_ivars(node) do |nested_ivar|
|
32
|
-
add_offense(nested_ivar)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def find_nested_ivars(node, &block)
|
39
|
-
node.each_child_node do |child|
|
40
|
-
if child.ivasgn_type? || child.ivar_type?
|
41
|
-
yield(child)
|
42
|
-
elsif child.children.any?
|
43
|
-
find_nested_ivars(child, &block)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module AnyCable
|
8
|
-
# Checks for periodical timers usage.
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# class MyChannel < ApplicationCable::Channel
|
13
|
-
# periodically(:do_something, every: 2.seconds)
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
class PeriodicalTimers < RuboCop::Cop::Cop
|
17
|
-
MSG = "Periodical Timers are not supported in AnyCable"
|
18
|
-
|
19
|
-
def_node_matcher :calls_periodically?, <<-PATTERN
|
20
|
-
(send _ :periodically ...)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
add_offense(node) if calls_periodically?(node)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module AnyCable
|
8
|
-
# Checks for #stream_from calls with custom callbacks or coders.
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# class MyChannel < ApplicationCable::Channel
|
13
|
-
# def follow
|
14
|
-
# stream_for(room) {}
|
15
|
-
# end
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# class MyChannel < ApplicationCable::Channel
|
19
|
-
# def follow
|
20
|
-
# stream_from("all", -> {})
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# class MyChannel < ApplicationCable::Channel
|
25
|
-
# def follow
|
26
|
-
# stream_from("all", coder: SomeCoder)
|
27
|
-
# end
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# # good
|
31
|
-
# class MyChannel < ApplicationCable::Channel
|
32
|
-
# def follow
|
33
|
-
# stream_from "all"
|
34
|
-
# end
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
class StreamFrom < RuboCop::Cop::Cop
|
38
|
-
def_node_matcher :stream_from_with_block?, <<-PATTERN
|
39
|
-
(block {(send _ :stream_from ...) (send _ :stream_for ...)} ...)
|
40
|
-
PATTERN
|
41
|
-
|
42
|
-
def_node_matcher :stream_from_with_callback?, <<-PATTERN
|
43
|
-
{(send _ :stream_from str_type? (block (send nil? :lambda) ...)) (send _ :stream_for ... (block (send nil? :lambda) ...))}
|
44
|
-
PATTERN
|
45
|
-
|
46
|
-
def_node_matcher :args_of_stream_from, <<-PATTERN
|
47
|
-
{(send _ :stream_from str_type? $...) (send _ :stream_for $...)}
|
48
|
-
PATTERN
|
49
|
-
|
50
|
-
def_node_matcher :coder_symbol?, "(pair (sym :coder) ...)"
|
51
|
-
|
52
|
-
def_node_matcher :active_support_json?, <<-PATTERN
|
53
|
-
(pair _ (const (const nil? :ActiveSupport) :JSON))
|
54
|
-
PATTERN
|
55
|
-
|
56
|
-
def on_block(node)
|
57
|
-
add_callback_offense(node) if stream_from_with_block?(node)
|
58
|
-
end
|
59
|
-
|
60
|
-
def on_send(node)
|
61
|
-
if stream_from_with_callback?(node)
|
62
|
-
add_callback_offense(node)
|
63
|
-
return
|
64
|
-
end
|
65
|
-
|
66
|
-
args = args_of_stream_from(node)
|
67
|
-
find_coders(args) { |coder| add_custom_coder_offense(coder) }
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def find_coders(args)
|
73
|
-
return if args.nil?
|
74
|
-
|
75
|
-
args.select(&:hash_type?).each do |arg|
|
76
|
-
arg.each_child_node do |pair|
|
77
|
-
yield(pair) if coder_symbol?(pair) && !active_support_json?(pair)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def add_callback_offense(node)
|
83
|
-
add_offense(
|
84
|
-
node,
|
85
|
-
location: :expression,
|
86
|
-
message: "Custom stream callbacks are not supported in AnyCable"
|
87
|
-
)
|
88
|
-
end
|
89
|
-
|
90
|
-
def add_custom_coder_offense(node)
|
91
|
-
add_offense(
|
92
|
-
node,
|
93
|
-
location: :expression,
|
94
|
-
message: "Custom coders are not supported in AnyCable"
|
95
|
-
)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
require "pathname"
|
5
|
-
|
6
|
-
require_relative "rubocop/cops/anycable/stream_from"
|
7
|
-
require_relative "rubocop/cops/anycable/periodical_timers"
|
8
|
-
require_relative "rubocop/cops/anycable/instance_vars"
|
9
|
-
|
10
|
-
module RuboCop
|
11
|
-
module AnyCable # :nodoc:
|
12
|
-
CONFIG_DEFAULT = Pathname.new(__dir__).join("rubocop", "config", "default.yml").freeze
|
13
|
-
|
14
|
-
# Merge anycable config into default configuration
|
15
|
-
# See https://github.com/backus/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
|
16
|
-
def self.inject!
|
17
|
-
path = CONFIG_DEFAULT.to_s
|
18
|
-
puts "configuration from #{path}" if ConfigLoader.debug?
|
19
|
-
hash = ConfigLoader.send(:load_yaml_configuration, path)
|
20
|
-
config = Config.new(hash, path)
|
21
|
-
config = ConfigLoader.merge_with_default(config, path)
|
22
|
-
ConfigLoader.instance_variable_set(:@default_configuration, config)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
RuboCop::AnyCable.inject!
|