anycable-rails-core 1.5.4 → 1.5.6
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 +6 -0
- data/lib/anycable/rails/action_cable_ext/channel.rb +0 -11
- data/lib/anycable/rails/compatibility/rubocop.rb +2 -25
- data/lib/anycable/rails/connection.rb +58 -33
- data/lib/anycable/rails/{compatibility/rubocop → rubocop}/cops/anycable/instance_vars.rb +1 -1
- data/lib/anycable/rails/{compatibility/rubocop → rubocop}/cops/anycable/periodical_timers.rb +1 -1
- data/lib/anycable/rails/{compatibility/rubocop → rubocop}/cops/anycable/stream_from.rb +3 -5
- data/lib/anycable/rails/rubocop.rb +27 -0
- data/lib/anycable/rails/version.rb +1 -1
- data/lib/anycable/rails.rb +1 -1
- data/lib/generators/anycable/setup/templates/config/anycable.yml.tt +1 -1
- metadata +10 -9
- /data/lib/anycable/rails/{compatibility/rubocop → rubocop}/config/default.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06a551d757afa07138babbf351024554d52b667ab35893bc995cc1fb56edd8af
|
4
|
+
data.tar.gz: c630ecf586cfd0068b0d248c00dc1372ffd7d83a3abf0e76dc9ecd52ae960a7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d46a5b21269ef7cb9cfc562ecee2cfd9830e055dd18fb20bce468409f0a84bc3ca3dc1ba56d9d340202039de3ab93aeba2e600388b7130b99bff101cbf00448
|
7
|
+
data.tar.gz: 64a083bf7d4046b5a1bfa57058f0aa1cedded844067b15f5f9ea660a8d5291bbe2c8f6db6c4a63768f2d17f67d40bb920f4abe8e55b9fbc9241f72c4a4d9c587
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.5.5 (2024-12-12)
|
6
|
+
|
7
|
+
- Publish RuboCop cops as a separate gem (`rubocop-anycable-rails`). ([@palkan][])
|
8
|
+
|
9
|
+
- Upgrade RuboCop cops. ([@palkan][])
|
10
|
+
|
5
11
|
## 1.5.4 (2024-10-08)
|
6
12
|
|
7
13
|
- Add [actioncable-next](https://github.com/anycable/actioncable-next) support. ([@palkan][])
|
@@ -3,17 +3,6 @@
|
|
3
3
|
require "action_cable"
|
4
4
|
|
5
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
6
|
def start_periodic_timers
|
18
7
|
super unless anycabled?
|
19
8
|
end
|
@@ -1,27 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
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!
|
3
|
+
# For backwards compatibility
|
4
|
+
require_relative "../rubocop"
|
@@ -31,15 +31,65 @@ module AnyCable
|
|
31
31
|
end
|
32
32
|
|
33
33
|
refine ActionCable::Connection::Subscriptions do
|
34
|
-
#
|
35
|
-
|
36
|
-
|
34
|
+
# Override the original #execute_command to pre-initialize the channel for unsubscribe/message and
|
35
|
+
# return true/false to indicate successful/unsuccessful subscription.
|
36
|
+
# We also must not lose any exceptions raised in the process.
|
37
|
+
def execute_rpc_command(data)
|
38
|
+
# First, verify the channel name
|
39
|
+
raise "Channel not found: #{ActiveSupport::JSON.decode(data["identifier"]).fetch("channel")}" unless subscription_class_from_identifier(data["identifier"])
|
40
|
+
|
41
|
+
if data["command"] == "subscribe"
|
42
|
+
add data
|
43
|
+
subscription = subscriptions[data["identifier"]]
|
44
|
+
return !(subscription.nil? || subscription.rejected?)
|
45
|
+
end
|
46
|
+
|
47
|
+
load(data["identifier"])
|
37
48
|
|
38
|
-
|
39
|
-
|
49
|
+
case data["command"]
|
50
|
+
when "unsubscribe"
|
51
|
+
remove data
|
52
|
+
when "message"
|
53
|
+
perform_action data
|
54
|
+
when "whisper"
|
55
|
+
whisper data
|
56
|
+
else
|
57
|
+
raise UnknownCommandError, data["command"]
|
40
58
|
end
|
41
59
|
|
42
|
-
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
# Restore channels from the list of identifiers and the state
|
64
|
+
def restore(subscriptions, istate)
|
65
|
+
subscriptions.each do |id|
|
66
|
+
channel = load(id)
|
67
|
+
channel.__istate__ = ActiveSupport::JSON.decode(istate[id]) if istate[id]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Find or create a channel for a given identifier
|
72
|
+
def load(identifier)
|
73
|
+
return subscriptions[identifier] if subscriptions[identifier]
|
74
|
+
|
75
|
+
subscription = subscription_from_identifier(identifier)
|
76
|
+
raise "Channel not found: #{ActiveSupport::JSON.decode(identifier).fetch("channel")}" unless subscription
|
77
|
+
|
78
|
+
subscriptions[identifier] = subscription
|
79
|
+
end
|
80
|
+
|
81
|
+
def subscription_class_from_identifier(id_key)
|
82
|
+
id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
|
83
|
+
id_options[:channel].safe_constantize
|
84
|
+
end
|
85
|
+
|
86
|
+
def subscription_from_identifier(id_key)
|
87
|
+
subscription_klass = subscription_class_from_identifier(id_key)
|
88
|
+
|
89
|
+
if subscription_klass && subscription_klass < ActionCable::Channel::Base
|
90
|
+
id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
|
91
|
+
subscription_klass.new(connection, id_key, id_options)
|
92
|
+
end
|
43
93
|
end
|
44
94
|
end
|
45
95
|
end)
|
@@ -74,15 +124,8 @@ module AnyCable
|
|
74
124
|
conn.cached_ids = {}
|
75
125
|
conn.anycable_request_builder = self
|
76
126
|
|
77
|
-
return unless subscriptions
|
78
|
-
|
79
127
|
# Pre-initialize channels (for disconnect)
|
80
|
-
subscriptions.
|
81
|
-
channel = conn.subscriptions.fetch(id)
|
82
|
-
next unless socket.istate[id]
|
83
|
-
|
84
|
-
channel.__istate__ = ActiveSupport::JSON.decode(socket.istate[id])
|
85
|
-
end
|
128
|
+
conn.subscriptions.restore(subscriptions, socket.istate) if subscriptions
|
86
129
|
end
|
87
130
|
|
88
131
|
def handle_open
|
@@ -111,26 +154,8 @@ module AnyCable
|
|
111
154
|
|
112
155
|
def handle_channel_command(identifier, command, data)
|
113
156
|
conn.run_callbacks :command do
|
114
|
-
|
115
|
-
# since we MUST return true of false, depending on the status
|
116
|
-
# of execution
|
117
|
-
channel = conn.subscriptions.fetch(identifier)
|
118
|
-
case command
|
119
|
-
when "subscribe"
|
120
|
-
channel.handle_subscribe
|
121
|
-
!channel.rejected?
|
122
|
-
when "unsubscribe"
|
123
|
-
conn.subscriptions.remove_subscription(channel)
|
124
|
-
true
|
125
|
-
when "message"
|
126
|
-
channel.perform_action ActiveSupport::JSON.decode(data)
|
127
|
-
true
|
128
|
-
else
|
129
|
-
false
|
130
|
-
end
|
157
|
+
conn.subscriptions.execute_rpc_command({"command" => command, "identifier" => identifier, "data" => data})
|
131
158
|
end
|
132
|
-
# Support rescue_from
|
133
|
-
# https://github.com/rails/rails/commit/d2571e560c62116f60429c933d0c41a0e249b58b
|
134
159
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
135
160
|
rescue_with_handler(e) || raise
|
136
161
|
false
|
data/lib/anycable/rails/{compatibility/rubocop → rubocop}/cops/anycable/periodical_timers.rb
RENAMED
@@ -13,7 +13,7 @@ module RuboCop
|
|
13
13
|
# periodically(:do_something, every: 2.seconds)
|
14
14
|
# end
|
15
15
|
#
|
16
|
-
class PeriodicalTimers < RuboCop::Cop::
|
16
|
+
class PeriodicalTimers < RuboCop::Cop::Base
|
17
17
|
MSG = "Periodical Timers are not supported in AnyCable"
|
18
18
|
|
19
19
|
def_node_matcher :calls_periodically?, <<-PATTERN
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
# end
|
35
35
|
# end
|
36
36
|
#
|
37
|
-
class StreamFrom < RuboCop::Cop::
|
37
|
+
class StreamFrom < RuboCop::Cop::Base
|
38
38
|
def_node_matcher :stream_from_with_block?, <<-PATTERN
|
39
39
|
(block {(send _ :stream_from ...) (send _ :stream_for ...)} ...)
|
40
40
|
PATTERN
|
@@ -81,16 +81,14 @@ module RuboCop
|
|
81
81
|
|
82
82
|
def add_callback_offense(node)
|
83
83
|
add_offense(
|
84
|
-
node,
|
85
|
-
location: :expression,
|
84
|
+
node.loc.expression,
|
86
85
|
message: "Custom stream callbacks are not supported in AnyCable"
|
87
86
|
)
|
88
87
|
end
|
89
88
|
|
90
89
|
def add_custom_coder_offense(node)
|
91
90
|
add_offense(
|
92
|
-
node,
|
93
|
-
location: :expression,
|
91
|
+
node.loc.expression,
|
94
92
|
message: "Custom coders are not supported in AnyCable"
|
95
93
|
)
|
96
94
|
end
|
@@ -0,0 +1,27 @@
|
|
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!
|
data/lib/anycable/rails.rb
CHANGED
@@ -84,7 +84,7 @@ end
|
|
84
84
|
|
85
85
|
# Warn if application has been already initialized.
|
86
86
|
# AnyCable should be loaded before initialization in order to work correctly.
|
87
|
-
if defined?(::Rails) && ::Rails.application
|
87
|
+
if defined?(::Rails) && ::Rails.application&.initialized?
|
88
88
|
puts("\n**************************************************")
|
89
89
|
puts(
|
90
90
|
"⛔️ WARNING: AnyCable loaded after application initialization. Might not work correctly.\n" \
|
@@ -23,7 +23,7 @@ default: &default
|
|
23
23
|
<%- else -%>
|
24
24
|
# Use HTTP broadcaster
|
25
25
|
broadcast_adapter: http
|
26
|
-
http_broadcast_url: "http://localhost:8090/
|
26
|
+
http_broadcast_url: "http://localhost:8090/_broadcast"
|
27
27
|
<%- end -%>
|
28
28
|
<%- if redis? -%>
|
29
29
|
# You can use REDIS_URL env var to configure Redis URL.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable-rails-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anycable-core
|
@@ -80,10 +80,6 @@ files:
|
|
80
80
|
- lib/anycable/rails/channel_state.rb
|
81
81
|
- lib/anycable/rails/compatibility.rb
|
82
82
|
- lib/anycable/rails/compatibility/rubocop.rb
|
83
|
-
- lib/anycable/rails/compatibility/rubocop/config/default.yml
|
84
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb
|
85
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb
|
86
|
-
- lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb
|
87
83
|
- lib/anycable/rails/config.rb
|
88
84
|
- lib/anycable/rails/connection.rb
|
89
85
|
- lib/anycable/rails/connection_factory.rb
|
@@ -105,6 +101,11 @@ files:
|
|
105
101
|
- lib/anycable/rails/pubsub_channel.rb
|
106
102
|
- lib/anycable/rails/rack.rb
|
107
103
|
- lib/anycable/rails/railtie.rb
|
104
|
+
- lib/anycable/rails/rubocop.rb
|
105
|
+
- lib/anycable/rails/rubocop/config/default.yml
|
106
|
+
- lib/anycable/rails/rubocop/cops/anycable/instance_vars.rb
|
107
|
+
- lib/anycable/rails/rubocop/cops/anycable/periodical_timers.rb
|
108
|
+
- lib/anycable/rails/rubocop/cops/anycable/stream_from.rb
|
108
109
|
- lib/anycable/rails/socket_id_tracking.rb
|
109
110
|
- lib/anycable/rails/version.rb
|
110
111
|
- lib/generators/anycable/bin/USAGE
|
@@ -130,7 +131,7 @@ metadata:
|
|
130
131
|
homepage_uri: https://anycable.io/
|
131
132
|
source_code_uri: http://github.com/anycable/anycable-rails
|
132
133
|
funding_uri: https://github.com/sponsors/anycable
|
133
|
-
post_install_message:
|
134
|
+
post_install_message:
|
134
135
|
rdoc_options: []
|
135
136
|
require_paths:
|
136
137
|
- lib
|
@@ -146,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
147
|
version: '0'
|
147
148
|
requirements: []
|
148
149
|
rubygems_version: 3.4.19
|
149
|
-
signing_key:
|
150
|
+
signing_key:
|
150
151
|
specification_version: 4
|
151
152
|
summary: AnyCable integration for Rails (w/o RPC dependencies)
|
152
153
|
test_files: []
|
File without changes
|