anycable-rails 1.0.0.rc1 → 1.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 +4 -4
- data/CHANGELOG.md +22 -1
- data/lib/anycable/rails.rb +1 -1
- data/lib/anycable/rails/actioncable/connection.rb +17 -0
- data/lib/anycable/rails/actioncable/connection/persistent_session.rb +7 -3
- data/lib/anycable/rails/actioncable/testing.rb +35 -0
- data/lib/anycable/rails/channel_state.rb +2 -4
- data/lib/anycable/rails/railtie.rb +8 -8
- data/lib/anycable/rails/version.rb +1 -1
- data/lib/generators/anycable/download/USAGE +1 -1
- data/lib/generators/anycable/download/download_generator.rb +12 -6
- data/lib/generators/anycable/setup/setup_generator.rb +41 -7
- data/lib/generators/anycable/setup/templates/Procfile.dev.tt +6 -0
- data/lib/generators/anycable/setup/templates/config/anycable.yml.tt +10 -3
- metadata +13 -12
- data/lib/generators/anycable/setup/templates/Procfile.dev +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2c1f822cbb79135290b3c404544d937f0f083751657057b7bdd4445a33a95f1
|
4
|
+
data.tar.gz: ae4f5e42da49c8f668ee2cf56a434e30872d04cee9bc3596f914fb2e48404ac1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55bb99bacfdbd2b29120e29598aedc467f56325096602c7713bc2bfee9c4c40f826089ee4dd4d76e80d7171bdd1989db0d21c002edae0e429174509d24f8d836
|
7
|
+
data.tar.gz: 2ee8318ebd5c27dd95b21bd784c75d0d78da08538f1dd466235b889485d2229a4f35202b036a422466f38422905fbda16f84a028ecb3772e0669ce2bfc203dda
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
##
|
3
|
+
## master
|
4
|
+
|
5
|
+
## 1.0.1 (2020-07-07)
|
6
|
+
|
7
|
+
- Fixed patching Action Cable testing classes. ([@palkan][])
|
8
|
+
|
9
|
+
## 1.0.0 (2020-07-01)
|
10
|
+
|
11
|
+
- Support `rescue_from` in connections (Rails 6.1). ([@palkan][])
|
12
|
+
|
13
|
+
- Make AnyCable patches compatible with Action Cable testing. ([@palkan][])
|
14
|
+
|
15
|
+
- Do not add localhost `redis_url` to `anycable.yml` when Docker development method is chosen in `anycable:setup`. ([@palkan][])
|
16
|
+
|
17
|
+
- Fix connection identifiers deserialization regression. ([@palkan][])
|
18
|
+
|
19
|
+
Using non-strings or non-GlobalId-encoded objects was broken.
|
20
|
+
|
21
|
+
- Improve `anycable:setup` generator. ([@palkan][])
|
22
|
+
|
23
|
+
Update Docker snippet, do not enable persistent sessions automatically,
|
24
|
+
fix setting `config.action_cable.url` in environment configuration.
|
4
25
|
|
5
26
|
- Add `state_attr_accessor` for channels. ([@palkan][])
|
6
27
|
|
data/lib/anycable/rails.rb
CHANGED
@@ -35,7 +35,7 @@ module AnyCable
|
|
35
35
|
# If the resulting object is a Hash, make it indifferent
|
36
36
|
def deserialize(str, json: false)
|
37
37
|
str.yield_self do |val|
|
38
|
-
next unless val.is_a?(String)
|
38
|
+
next val unless val.is_a?(String)
|
39
39
|
|
40
40
|
gval = GlobalID::Locator.locate(val)
|
41
41
|
return gval if gval
|
@@ -21,6 +21,8 @@ module ActionCable
|
|
21
21
|
|
22
22
|
attr_reader :socket
|
23
23
|
|
24
|
+
alias anycable_socket socket
|
25
|
+
|
24
26
|
delegate :env, :session, to: :request
|
25
27
|
|
26
28
|
class << self
|
@@ -196,3 +198,18 @@ module ActionCable
|
|
196
198
|
# rubocop:enable Metrics/ClassLength
|
197
199
|
end
|
198
200
|
end
|
201
|
+
|
202
|
+
# Support rescue_from
|
203
|
+
# https://github.com/rails/rails/commit/d2571e560c62116f60429c933d0c41a0e249b58b
|
204
|
+
if ActionCable::Connection::Base.respond_to?(:rescue_from)
|
205
|
+
ActionCable::Connection::Base.prepend(Module.new do
|
206
|
+
def handle_channel_command(*)
|
207
|
+
super
|
208
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
209
|
+
rescue_with_handler(e) || raise
|
210
|
+
false
|
211
|
+
end
|
212
|
+
end)
|
213
|
+
end
|
214
|
+
|
215
|
+
require "anycable/rails/actioncable/testing" if ::Rails.env.test?
|
@@ -15,16 +15,20 @@ module ActionCable
|
|
15
15
|
return super unless socket.session
|
16
16
|
|
17
17
|
super.tap do |req|
|
18
|
-
req.env[Rack::RACK_SESSION] =
|
19
|
-
AnyCable::Rails::SessionProxy.new(req.env[Rack::RACK_SESSION], socket.session)
|
18
|
+
req.env[::Rack::RACK_SESSION] =
|
19
|
+
AnyCable::Rails::SessionProxy.new(req.env[::Rack::RACK_SESSION], socket.session)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def commit_session!
|
24
|
-
return unless request_loaded? && request.session.loaded?
|
24
|
+
return unless request_loaded? && request.session.respond_to?(:loaded?) && request.session.loaded?
|
25
25
|
|
26
26
|
socket.session = request.session.to_json
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
::ActionCable::Connection::Base.prepend(
|
33
|
+
::ActionCable::Connection::PersistentSession
|
34
|
+
)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file contains patches to Action Cable testing modules
|
4
|
+
|
5
|
+
# Trigger autoload (if constant is defined)
|
6
|
+
begin
|
7
|
+
ActionCable::Channel::TestCase # rubocop:disable Lint/Void
|
8
|
+
ActionCable::Connection::TestCase # rubocop:disable Lint/Void
|
9
|
+
rescue NameError
|
10
|
+
return
|
11
|
+
end
|
12
|
+
|
13
|
+
ActionCable::Channel::ChannelStub.prepend(Module.new do
|
14
|
+
def subscribe_to_channel
|
15
|
+
# allocate @streams
|
16
|
+
streams
|
17
|
+
handle_subscribe
|
18
|
+
end
|
19
|
+
end)
|
20
|
+
|
21
|
+
ActionCable::Channel::ConnectionStub.prepend(Module.new do
|
22
|
+
def socket
|
23
|
+
@socket ||= AnyCable::Socket.new(env: {})
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :anycable_socket, :socket
|
27
|
+
end)
|
28
|
+
|
29
|
+
ActionCable::Connection::TestConnection.prepend(Module.new do
|
30
|
+
def initialize(request)
|
31
|
+
@request = request
|
32
|
+
@cached_ids = {}
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end)
|
@@ -5,18 +5,16 @@ module AnyCable
|
|
5
5
|
module ChannelState
|
6
6
|
module ClassMethods
|
7
7
|
def state_attr_accessor(*names)
|
8
|
-
return attr_accessor(*names) unless AnyCable::Rails.enabled?
|
9
|
-
|
10
8
|
names.each do |name|
|
11
9
|
channel_state_attributes << name
|
12
10
|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
13
11
|
def #{name}
|
14
12
|
return @#{name} if instance_variable_defined?(:@#{name})
|
15
|
-
@#{name} = AnyCable::Rails.deserialize(connection.socket.istate["#{name}"], json: true)
|
13
|
+
@#{name} = AnyCable::Rails.deserialize(connection.socket.istate["#{name}"], json: true) if connection.anycable_socket
|
16
14
|
end
|
17
15
|
|
18
16
|
def #{name}=(val)
|
19
|
-
connection.socket.istate["#{name}"] = AnyCable::Rails.serialize(val, json: true)
|
17
|
+
connection.socket.istate["#{name}"] = AnyCable::Rails.serialize(val, json: true) if connection.anycable_socket
|
20
18
|
instance_variable_set(:@#{name}, val)
|
21
19
|
end
|
22
20
|
RUBY
|
@@ -43,18 +43,18 @@ module AnyCable
|
|
43
43
|
|
44
44
|
initializer "anycable.connection_factory", after: "action_cable.set_configs" do |app|
|
45
45
|
ActiveSupport.on_load(:action_cable) do
|
46
|
+
# Add AnyCable patch method stub (we use it in ChannelState to distinguish between Action Cable and AnyCable)
|
47
|
+
# NOTE: Method could be already defined if patch was loaded manually
|
48
|
+
ActionCable::Connection::Base.attr_reader(:anycable_socket) unless ActionCable::Connection::Base.method_defined?(:anycable_socket)
|
49
|
+
|
50
|
+
app.config.to_prepare do
|
51
|
+
AnyCable.connection_factory = ActionCable.server.config.connection_class.call
|
52
|
+
end
|
53
|
+
|
46
54
|
if AnyCable::Rails.enabled?
|
47
55
|
require "anycable/rails/actioncable/connection"
|
48
|
-
|
49
56
|
if AnyCable.config.persistent_session_enabled
|
50
57
|
require "anycable/rails/actioncable/connection/persistent_session"
|
51
|
-
::ActionCable::Connection::Base.prepend(
|
52
|
-
::ActionCable::Connection::PersistentSession
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
|
-
app.config.to_prepare do
|
57
|
-
AnyCable.connection_factory = ActionCable.server.config.connection_class.call
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -9,8 +9,7 @@ module AnyCableRailsGenerators
|
|
9
9
|
|
10
10
|
include WithOSHelpers
|
11
11
|
|
12
|
-
|
13
|
-
VERSION = "1.0.0.preview1"
|
12
|
+
VERSION = "latest"
|
14
13
|
|
15
14
|
class_option :bin_path,
|
16
15
|
type: :string,
|
@@ -35,20 +34,27 @@ module AnyCableRailsGenerators
|
|
35
34
|
private
|
36
35
|
|
37
36
|
def release_url(version)
|
37
|
+
return latest_release_url(version) if version == "latest"
|
38
|
+
|
38
39
|
if Gem::Version.new(version).segments.first >= 1
|
39
|
-
new_release_url(version)
|
40
|
+
new_release_url("v#{version}")
|
40
41
|
else
|
41
|
-
legacy_release_url(version)
|
42
|
+
legacy_release_url("v#{version}")
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
def legacy_release_url(version)
|
46
|
-
"https://github.com/anycable/anycable-go/releases/download
|
47
|
+
"https://github.com/anycable/anycable-go/releases/download/#{version}/" \
|
47
48
|
"anycable-go-v#{version}-#{os_name}-#{cpu_name}"
|
48
49
|
end
|
49
50
|
|
50
51
|
def new_release_url(version)
|
51
|
-
"https://github.com/anycable/anycable-go/releases/download
|
52
|
+
"https://github.com/anycable/anycable-go/releases/download/#{version}/" \
|
53
|
+
"anycable-go-#{os_name}-#{cpu_name}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def latest_release_url(version)
|
57
|
+
"https://github.com/anycable/anycable-go/releases/latest/download/" \
|
52
58
|
"anycable-go-#{os_name}-#{cpu_name}"
|
53
59
|
end
|
54
60
|
|
@@ -49,14 +49,18 @@ module AnyCableRailsGenerators
|
|
49
49
|
environment(nil, env: :development) do
|
50
50
|
<<~SNIPPET
|
51
51
|
# Specify AnyCable WebSocket server URL to use by JS client
|
52
|
-
config.
|
52
|
+
config.after_initialize do
|
53
|
+
config.action_cable.url = ActionCable.server.config.url = ENV.fetch("CABLE_URL", "ws://localhost:8080/cable") if AnyCable::Rails.enabled?
|
54
|
+
end
|
53
55
|
SNIPPET
|
54
56
|
end
|
55
57
|
|
56
58
|
environment(nil, env: :production) do
|
57
59
|
<<~SNIPPET
|
58
60
|
# Specify AnyCable WebSocket server URL to use by JS client
|
59
|
-
config.
|
61
|
+
config.after_initialize do
|
62
|
+
config.action_cable.url = ActionCable.server.config.url = ENV.fetch("CABLE_URL") if AnyCable::Rails.enabled?
|
63
|
+
end
|
60
64
|
SNIPPET
|
61
65
|
end
|
62
66
|
|
@@ -111,6 +115,12 @@ module AnyCableRailsGenerators
|
|
111
115
|
say_status :info, "✅ config/initializers/anycable.rb with Devise configuration has been added"
|
112
116
|
end
|
113
117
|
|
118
|
+
def stimulus_reflex
|
119
|
+
return unless stimulus_reflex?
|
120
|
+
|
121
|
+
say_status :help, "⚠️ Please, check out the documentation on using AnyCable with Stimulus Reflex: https://docs.anycable.io/v1/#/ruby/stimulus_reflex"
|
122
|
+
end
|
123
|
+
|
114
124
|
def rubocop_compatibility
|
115
125
|
return unless rubocop?
|
116
126
|
|
@@ -133,6 +143,10 @@ module AnyCableRailsGenerators
|
|
133
143
|
!!gemfile_lock&.match?(/^\s+redis\b/)
|
134
144
|
end
|
135
145
|
|
146
|
+
def webpacker?
|
147
|
+
!!gemfile_lock&.match?(/^\s+webpacker\b/)
|
148
|
+
end
|
149
|
+
|
136
150
|
def rubocop?
|
137
151
|
!!gemfile_lock&.match?(/^\s+rubocop\b/)
|
138
152
|
end
|
@@ -149,21 +163,26 @@ module AnyCableRailsGenerators
|
|
149
163
|
end
|
150
164
|
|
151
165
|
def install_for_docker
|
166
|
+
# Remove localhost from configuraiton
|
167
|
+
gsub_file "config/anycable.yml", /^.*redis_url:.*localhost[^\n]+\n/, ""
|
168
|
+
|
152
169
|
say_status :help, "️️⚠️ Docker development configuration could vary", :yellow
|
153
170
|
|
154
171
|
say "Here is an example snippet for docker-compose.yml:"
|
155
172
|
say <<~YML
|
156
173
|
─────────────────────────────────────────
|
157
174
|
ws:
|
158
|
-
image: anycable/anycable-go:1.0
|
175
|
+
image: anycable/anycable-go:1.0
|
159
176
|
ports:
|
160
177
|
- '8080:8080'
|
161
178
|
environment:
|
179
|
+
ANYCABLE_HOST: "0.0.0.0"
|
162
180
|
ANYCABLE_REDIS_URL: redis://redis:6379/0
|
163
181
|
ANYCABLE_RPC_HOST: anycable:50051
|
182
|
+
ANYCABLE_DEBUG: 1
|
164
183
|
depends_on:
|
165
|
-
|
166
|
-
|
184
|
+
redis:
|
185
|
+
condition: service_healthy
|
167
186
|
|
168
187
|
anycable:
|
169
188
|
<<: *backend
|
@@ -172,8 +191,13 @@ module AnyCableRailsGenerators
|
|
172
191
|
<<: *backend_environment
|
173
192
|
ANYCABLE_REDIS_URL: redis://redis:6379/0
|
174
193
|
ANYCABLE_RPC_HOST: 0.0.0.0:50051
|
194
|
+
ANYCABLE_DEBUG: 1
|
175
195
|
ports:
|
176
196
|
- '50051'
|
197
|
+
depends_on:
|
198
|
+
<<: *backend_depends_on
|
199
|
+
ws:
|
200
|
+
condition: service_started
|
177
201
|
─────────────────────────────────────────
|
178
202
|
YML
|
179
203
|
end
|
@@ -204,8 +228,8 @@ module AnyCableRailsGenerators
|
|
204
228
|
def template_proc_files
|
205
229
|
file_name = "Procfile.dev"
|
206
230
|
|
207
|
-
if
|
208
|
-
append_file file_name,
|
231
|
+
if file_exists?(file_name)
|
232
|
+
append_file file_name, "anycable: bundle exec anycable\nws: anycable-go#{anycable_go_options}", force: true
|
209
233
|
else
|
210
234
|
say_status :help, "💡 We recommend using Hivemind to manage multiple processes in development 👉 https://github.com/DarthSim/hivemind", :yellow
|
211
235
|
|
@@ -242,5 +266,15 @@ module AnyCableRailsGenerators
|
|
242
266
|
args << "--version #{opts[:version]}" if opts[:version]
|
243
267
|
end.join(" ")
|
244
268
|
end
|
269
|
+
|
270
|
+
def anycable_go_options
|
271
|
+
redis? ? " --port=8080" : " --port=8080 --broadcast_adapter=http"
|
272
|
+
end
|
273
|
+
|
274
|
+
def file_exists?(name)
|
275
|
+
in_root do
|
276
|
+
return File.file?(name)
|
277
|
+
end
|
278
|
+
end
|
245
279
|
end
|
246
280
|
end
|
@@ -12,8 +12,8 @@
|
|
12
12
|
default: &default
|
13
13
|
# Turn on/off access logs ("Started..." and "Finished...")
|
14
14
|
access_logs_disabled: false
|
15
|
-
# Persist "dirty" session between RPC calls (might be required for
|
16
|
-
persistent_session_enabled:
|
15
|
+
# Persist "dirty" session between RPC calls (might be required for apps using stimulus_reflex <3.0)
|
16
|
+
# persistent_session_enabled: true
|
17
17
|
# This is the host and the port to run AnyCable RPC server on.
|
18
18
|
# You must configure your WebSocket server to connect to it, e.g.:
|
19
19
|
# $ anycable-go --rpc-host="<rpc hostname>:50051"
|
@@ -30,10 +30,17 @@ default: &default
|
|
30
30
|
# Use the same channel name for WebSocket server, e.g.:
|
31
31
|
# $ anycable-go --redis-channel="__anycable__"
|
32
32
|
redis_channel: "__anycable__"
|
33
|
+
<%- if redis? -%>
|
34
|
+
# You can use REDIS_URL env var to configure Redis URL.
|
35
|
+
# Localhost is used by default.
|
36
|
+
# redis_url: "redis://localhost:6379/1"
|
37
|
+
<%- end -%>
|
33
38
|
|
34
39
|
development:
|
35
40
|
<<: *default
|
36
|
-
|
41
|
+
|
42
|
+
test:
|
43
|
+
<<: *default
|
37
44
|
|
38
45
|
production:
|
39
46
|
<<: *default
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anycable
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.0.0
|
19
|
+
version: 1.0.0
|
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: 1.0.0
|
26
|
+
version: 1.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,19 +81,19 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '13.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec
|
84
|
+
name: rspec-rails
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 4.0.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 4.0.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/anycable/rails/actioncable/connection/persistent_session.rb
|
142
142
|
- lib/anycable/rails/actioncable/connection/serializable_identification.rb
|
143
143
|
- lib/anycable/rails/actioncable/remote_connections.rb
|
144
|
+
- lib/anycable/rails/actioncable/testing.rb
|
144
145
|
- lib/anycable/rails/channel_state.rb
|
145
146
|
- lib/anycable/rails/compatibility.rb
|
146
147
|
- lib/anycable/rails/compatibility/rubocop.rb
|
@@ -160,7 +161,7 @@ files:
|
|
160
161
|
- lib/generators/anycable/download/download_generator.rb
|
161
162
|
- lib/generators/anycable/setup/USAGE
|
162
163
|
- lib/generators/anycable/setup/setup_generator.rb
|
163
|
-
- lib/generators/anycable/setup/templates/Procfile.dev
|
164
|
+
- lib/generators/anycable/setup/templates/Procfile.dev.tt
|
164
165
|
- lib/generators/anycable/setup/templates/config/anycable.yml.tt
|
165
166
|
- lib/generators/anycable/setup/templates/config/cable.yml.tt
|
166
167
|
- lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt
|
@@ -185,9 +186,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
185
186
|
version: '2.5'
|
186
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
188
|
requirements:
|
188
|
-
- - "
|
189
|
+
- - ">="
|
189
190
|
- !ruby/object:Gem::Version
|
190
|
-
version:
|
191
|
+
version: '0'
|
191
192
|
requirements: []
|
192
193
|
rubygems_version: 3.0.6
|
193
194
|
signing_key:
|