actioncable 6.1.3.1 → 7.0.0.alpha1
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 -50
- data/MIT-LICENSE +1 -1
- data/app/assets/javascripts/action_cable.js +179 -255
- data/lib/action_cable/channel/broadcasting.rb +1 -1
- data/lib/action_cable/channel/streams.rb +5 -7
- data/lib/action_cable/channel/test_case.rb +1 -1
- data/lib/action_cable/connection/base.rb +3 -3
- data/lib/action_cable/connection/identification.rb +1 -1
- data/lib/action_cable/connection/subscriptions.rb +1 -1
- data/lib/action_cable/connection/tagged_logger_proxy.rb +2 -2
- data/lib/action_cable/engine.rb +9 -0
- data/lib/action_cable/gem_version.rb +4 -4
- data/lib/action_cable/helpers/action_cable_helper.rb +3 -2
- data/lib/action_cable/remote_connections.rb +1 -1
- data/lib/action_cable/server/broadcasting.rb +1 -1
- data/lib/action_cable/server/configuration.rb +1 -0
- data/lib/action_cable/server/worker/active_record_connection_management.rb +2 -2
- data/lib/action_cable/server/worker.rb +3 -4
- data/lib/action_cable/subscription_adapter/postgresql.rb +2 -2
- data/lib/action_cable/test_helper.rb +2 -2
- data/lib/action_cable.rb +1 -1
- data/lib/rails/generators/channel/USAGE +1 -1
- data/lib/rails/generators/channel/channel_generator.rb +79 -20
- data/lib/rails/generators/channel/templates/application_cable/{channel.rb.tt → channel.rb} +0 -0
- data/lib/rails/generators/channel/templates/application_cable/{connection.rb.tt → connection.rb} +0 -0
- data/lib/rails/generators/channel/templates/javascript/index.js.tt +1 -5
- metadata +15 -15
@@ -25,7 +25,7 @@ module ActionCable
|
|
25
25
|
serialize_broadcasting([ channel_name, model ])
|
26
26
|
end
|
27
27
|
|
28
|
-
def serialize_broadcasting(object)
|
28
|
+
def serialize_broadcasting(object) # :nodoc:
|
29
29
|
case
|
30
30
|
when object.is_a?(Array)
|
31
31
|
object.map { |m| serialize_broadcasting(m) }.join(":")
|
@@ -124,13 +124,11 @@ module ActionCable
|
|
124
124
|
end.clear
|
125
125
|
end
|
126
126
|
|
127
|
-
# Calls stream_for if
|
128
|
-
#
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if record
|
133
|
-
stream_for record
|
127
|
+
# Calls stream_for with the given <tt>model</tt> if it's present to start streaming,
|
128
|
+
# otherwise rejects the subscription.
|
129
|
+
def stream_or_reject_for(model)
|
130
|
+
if model
|
131
|
+
stream_for model
|
134
132
|
else
|
135
133
|
reject
|
136
134
|
end
|
@@ -246,7 +246,7 @@ module ActionCable
|
|
246
246
|
# Returns messages transmitted into channel
|
247
247
|
def transmissions
|
248
248
|
# Return only directly sent message (via #transmit)
|
249
|
-
connection.transmissions.
|
249
|
+
connection.transmissions.filter_map { |data| data["message"] }
|
250
250
|
end
|
251
251
|
|
252
252
|
# Enhance TestHelper assertions to handle non-String
|
@@ -68,7 +68,7 @@ module ActionCable
|
|
68
68
|
|
69
69
|
# Called by the server when a new WebSocket connection is established. This configures the callbacks intended for overwriting by the user.
|
70
70
|
# This method should not be called directly -- instead rely upon on the #connect (and #disconnect) callbacks.
|
71
|
-
def process
|
71
|
+
def process # :nodoc:
|
72
72
|
logger.info started_request_message
|
73
73
|
|
74
74
|
if websocket.possible? && allow_request_origin?
|
@@ -80,11 +80,11 @@ module ActionCable
|
|
80
80
|
|
81
81
|
# Decodes WebSocket messages and dispatches them to subscribed channels.
|
82
82
|
# WebSocket message transfer encoding is always JSON.
|
83
|
-
def receive(websocket_message)
|
83
|
+
def receive(websocket_message) # :nodoc:
|
84
84
|
send_async :dispatch_websocket_message, websocket_message
|
85
85
|
end
|
86
86
|
|
87
|
-
def dispatch_websocket_message(websocket_message)
|
87
|
+
def dispatch_websocket_message(websocket_message) # :nodoc:
|
88
88
|
if websocket.alive?
|
89
89
|
subscriptions.execute_command decode(websocket_message)
|
90
90
|
else
|
@@ -26,7 +26,7 @@ module ActionCable
|
|
26
26
|
# Return a single connection identifier that combines the value of all the registered identifiers into a single gid.
|
27
27
|
def connection_identifier
|
28
28
|
unless defined? @connection_identifier
|
29
|
-
@connection_identifier = connection_gid identifiers.
|
29
|
+
@connection_identifier = connection_gid identifiers.filter_map { |id| instance_variable_get("@#{id}") }
|
30
30
|
end
|
31
31
|
|
32
32
|
@connection_identifier
|
@@ -33,7 +33,7 @@ module ActionCable
|
|
33
33
|
|
34
34
|
subscription_klass = id_options[:channel].safe_constantize
|
35
35
|
|
36
|
-
if subscription_klass && ActionCable::Channel::Base
|
36
|
+
if subscription_klass && ActionCable::Channel::Base > subscription_klass
|
37
37
|
subscription = subscription_klass.new(connection, id_key, id_options)
|
38
38
|
subscriptions[id_key] = subscription
|
39
39
|
subscription.subscribe_to_channel
|
@@ -18,10 +18,10 @@ module ActionCable
|
|
18
18
|
@tags = @tags.uniq
|
19
19
|
end
|
20
20
|
|
21
|
-
def tag(logger)
|
21
|
+
def tag(logger, &block)
|
22
22
|
if logger.respond_to?(:tagged)
|
23
23
|
current_tags = tags - logger.formatter.current_tags
|
24
|
-
logger.tagged(*current_tags)
|
24
|
+
logger.tagged(*current_tags, &block)
|
25
25
|
else
|
26
26
|
yield
|
27
27
|
end
|
data/lib/action_cable/engine.rb
CHANGED
@@ -9,6 +9,7 @@ module ActionCable
|
|
9
9
|
class Engine < Rails::Engine # :nodoc:
|
10
10
|
config.action_cable = ActiveSupport::OrderedOptions.new
|
11
11
|
config.action_cable.mount_path = ActionCable::INTERNAL[:default_mount_path]
|
12
|
+
config.action_cable.precompile_assets = true
|
12
13
|
|
13
14
|
config.eager_load_namespaces << ActionCable
|
14
15
|
|
@@ -22,6 +23,14 @@ module ActionCable
|
|
22
23
|
ActiveSupport.on_load(:action_cable) { self.logger ||= ::Rails.logger }
|
23
24
|
end
|
24
25
|
|
26
|
+
initializer "action_cable.asset" do
|
27
|
+
config.after_initialize do |app|
|
28
|
+
if Rails.application.config.respond_to?(:assets) && app.config.action_cable.precompile_assets
|
29
|
+
Rails.application.config.assets.precompile += %w( actioncable.js actioncable.esm.js )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
25
34
|
initializer "action_cable.set_configs" do |app|
|
26
35
|
options = app.config.action_cable
|
27
36
|
options.allowed_request_origins ||= /https?:\/\/localhost:\d+/ if ::Rails.env.development?
|
@@ -8,14 +8,15 @@ module ActionCable
|
|
8
8
|
#
|
9
9
|
# <head>
|
10
10
|
# <%= action_cable_meta_tag %>
|
11
|
-
# <%= javascript_include_tag 'application', 'data-
|
11
|
+
# <%= javascript_include_tag 'application', 'data-turbo-track' => 'reload' %>
|
12
12
|
# </head>
|
13
13
|
#
|
14
14
|
# This is then used by Action Cable to determine the URL of your WebSocket server.
|
15
15
|
# Your JavaScript can then connect to the server without needing to specify the
|
16
16
|
# URL directly:
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# import Cable from "@rails/actioncable"
|
19
|
+
# window.Cable = Cable
|
19
20
|
# window.App = {}
|
20
21
|
# App.cable = Cable.createConsumer()
|
21
22
|
#
|
@@ -45,7 +45,7 @@ module ActionCable
|
|
45
45
|
|
46
46
|
# Uses the internal channel to disconnect the connection.
|
47
47
|
def disconnect
|
48
|
-
server.broadcast internal_channel, type: "disconnect"
|
48
|
+
server.broadcast internal_channel, { type: "disconnect" }
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns all the identifiers that were applied to this connection.
|
@@ -40,7 +40,7 @@ module ActionCable
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def broadcast(message)
|
43
|
-
server.logger.debug { "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}" }
|
43
|
+
server.logger.debug { "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect.truncate(300)}" }
|
44
44
|
|
45
45
|
payload = { broadcasting: broadcasting, message: message, coder: coder }
|
46
46
|
ActiveSupport::Notifications.instrument("broadcast.action_cable", payload) do
|
@@ -9,6 +9,7 @@ module ActionCable
|
|
9
9
|
attr_accessor :connection_class, :worker_pool_size
|
10
10
|
attr_accessor :disable_request_forgery_protection, :allowed_request_origins, :allow_same_origin_as_host
|
11
11
|
attr_accessor :cable, :url, :mount_path
|
12
|
+
attr_accessor :precompile_assets
|
12
13
|
|
13
14
|
def initialize
|
14
15
|
@log_tags = []
|
@@ -19,6 +19,7 @@ module ActionCable
|
|
19
19
|
|
20
20
|
def initialize(max_size: 5)
|
21
21
|
@executor = Concurrent::ThreadPoolExecutor.new(
|
22
|
+
name: "ActionCable",
|
22
23
|
min_threads: 1,
|
23
24
|
max_threads: max_size,
|
24
25
|
max_queue: 0,
|
@@ -35,12 +36,10 @@ module ActionCable
|
|
35
36
|
@executor.shuttingdown?
|
36
37
|
end
|
37
38
|
|
38
|
-
def work(connection)
|
39
|
+
def work(connection, &block)
|
39
40
|
self.connection = connection
|
40
41
|
|
41
|
-
run_callbacks :work
|
42
|
-
yield
|
43
|
-
end
|
42
|
+
run_callbacks :work, &block
|
44
43
|
ensure
|
45
44
|
self.connection = nil
|
46
45
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
gem "pg", "~> 1.1"
|
4
4
|
require "pg"
|
5
5
|
require "thread"
|
6
|
-
require "
|
6
|
+
require "openssl"
|
7
7
|
|
8
8
|
module ActionCable
|
9
9
|
module SubscriptionAdapter
|
@@ -58,7 +58,7 @@ module ActionCable
|
|
58
58
|
|
59
59
|
private
|
60
60
|
def channel_identifier(channel)
|
61
|
-
channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
|
61
|
+
channel.size > 63 ? OpenSSL::Digest::SHA1.hexdigest(channel) : channel
|
62
62
|
end
|
63
63
|
|
64
64
|
def listener
|
@@ -45,7 +45,7 @@ module ActionCable
|
|
45
45
|
def assert_broadcasts(stream, number, &block)
|
46
46
|
if block_given?
|
47
47
|
original_count = broadcasts_size(stream)
|
48
|
-
|
48
|
+
_assert_nothing_raised_or_warn("assert_broadcasts", &block)
|
49
49
|
new_count = broadcasts_size(stream)
|
50
50
|
actual_count = new_count - original_count
|
51
51
|
else
|
@@ -106,7 +106,7 @@ module ActionCable
|
|
106
106
|
old_messages = new_messages
|
107
107
|
clear_messages(stream)
|
108
108
|
|
109
|
-
|
109
|
+
_assert_nothing_raised_or_warn("assert_broadcast_on", &block)
|
110
110
|
new_messages = broadcasts(stream)
|
111
111
|
clear_messages(stream)
|
112
112
|
|
data/lib/action_cable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2015-
|
4
|
+
# Copyright (c) 2015-2021 Basecamp, LLC
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -13,39 +13,98 @@ module Rails
|
|
13
13
|
|
14
14
|
hook_for :test_framework
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def create_channel_files
|
17
|
+
create_shared_channel_files
|
18
|
+
create_channel_file
|
18
19
|
|
19
|
-
if
|
20
|
-
if
|
21
|
-
|
22
|
-
|
20
|
+
if using_javascript?
|
21
|
+
if first_setup_required?
|
22
|
+
create_shared_channel_javascript_files
|
23
|
+
import_channels_in_javascript_entrypoint
|
24
|
+
|
25
|
+
if using_importmap?
|
26
|
+
pin_javascript_dependencies
|
27
|
+
elsif using_node?
|
28
|
+
install_javascript_dependencies
|
29
|
+
end
|
23
30
|
end
|
24
31
|
|
25
|
-
|
32
|
+
create_channel_javascript_file
|
33
|
+
import_channel_in_javascript_entrypoint
|
26
34
|
end
|
27
|
-
|
28
|
-
generate_application_cable_files
|
29
35
|
end
|
30
36
|
|
31
37
|
private
|
38
|
+
def create_shared_channel_files
|
39
|
+
return if behavior != :invoke
|
40
|
+
|
41
|
+
copy_file "#{__dir__}/templates/application_cable/channel.rb",
|
42
|
+
"app/channels/application_cable/channel.rb"
|
43
|
+
copy_file "#{__dir__}/templates/application_cable/connection.rb",
|
44
|
+
"app/channels/application_cable/connection.rb"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_channel_file
|
48
|
+
template "channel.rb",
|
49
|
+
File.join("app/channels", class_path, "#{file_name}_channel.rb")
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_shared_channel_javascript_files
|
53
|
+
template "javascript/index.js", "app/javascript/channels/index.js"
|
54
|
+
template "javascript/consumer.js", "app/javascript/channels/consumer.js"
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_channel_javascript_file
|
58
|
+
channel_js_path = File.join("app/javascript/channels", class_path, "#{file_name}_channel")
|
59
|
+
js_template "javascript/channel", channel_js_path
|
60
|
+
gsub_file "#{channel_js_path}.js", /\.\/consumer/, "channels/consumer" unless using_node?
|
61
|
+
end
|
62
|
+
|
63
|
+
def import_channels_in_javascript_entrypoint
|
64
|
+
append_to_file "app/javascript/application.js",
|
65
|
+
using_node? ? %(import "./channels"\n) : %(import "channels"\n)
|
66
|
+
end
|
67
|
+
|
68
|
+
def import_channel_in_javascript_entrypoint
|
69
|
+
append_to_file "app/javascript/channels/index.js",
|
70
|
+
using_node? ? %(import "./#{file_name}_channel"\n) : %(import "channels/#{file_name}_channel"\n)
|
71
|
+
end
|
72
|
+
|
73
|
+
def install_javascript_dependencies
|
74
|
+
say "Installing JavaScript dependencies", :green
|
75
|
+
run "yarn add @rails/actioncable"
|
76
|
+
end
|
77
|
+
|
78
|
+
def pin_javascript_dependencies
|
79
|
+
append_to_file "config/importmap.rb", <<-RUBY
|
80
|
+
pin "@rails/actioncable", to: "actioncable.esm.js"
|
81
|
+
pin_all_from "app/javascript/channels", under: "channels"
|
82
|
+
RUBY
|
83
|
+
end
|
84
|
+
|
85
|
+
|
32
86
|
def file_name
|
33
87
|
@_file_name ||= super.sub(/_channel\z/i, "")
|
34
88
|
end
|
35
89
|
|
36
|
-
|
37
|
-
|
38
|
-
|
90
|
+
def first_setup_required?
|
91
|
+
!root.join("app/javascript/channels/index.js").exist?
|
92
|
+
end
|
39
93
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
]
|
94
|
+
def using_javascript?
|
95
|
+
@using_javascript ||= options[:assets] && root.join("app/javascript").exist?
|
96
|
+
end
|
44
97
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
98
|
+
def using_node?
|
99
|
+
@using_node ||= root.join("package.json").exist?
|
100
|
+
end
|
101
|
+
|
102
|
+
def using_importmap?
|
103
|
+
@using_importmap ||= root.join("config/importmap.rb").exist?
|
104
|
+
end
|
105
|
+
|
106
|
+
def root
|
107
|
+
@root ||= Pathname(destination_root)
|
49
108
|
end
|
50
109
|
end
|
51
110
|
end
|
File without changes
|
data/lib/rails/generators/channel/templates/application_cable/{connection.rb.tt → connection.rb}
RENAMED
File without changes
|
@@ -1,5 +1 @@
|
|
1
|
-
//
|
2
|
-
// Channel files must be named *_channel.js.
|
3
|
-
|
4
|
-
const channels = require.context('.', true, /_channel\.js$/)
|
5
|
-
channels.keys().forEach(channels)
|
1
|
+
// Import all the channels to be used by Action Cable
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actioncable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pratik Naik
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -17,28 +17,28 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - '='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 7.0.0.alpha1
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - '='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 7.0.0.alpha1
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: actionpack
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - '='
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 7.0.0.alpha1
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - '='
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 7.0.0.alpha1
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: nio4r
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,8 +127,8 @@ files:
|
|
127
127
|
- lib/action_cable/version.rb
|
128
128
|
- lib/rails/generators/channel/USAGE
|
129
129
|
- lib/rails/generators/channel/channel_generator.rb
|
130
|
-
- lib/rails/generators/channel/templates/application_cable/channel.rb
|
131
|
-
- lib/rails/generators/channel/templates/application_cable/connection.rb
|
130
|
+
- lib/rails/generators/channel/templates/application_cable/channel.rb
|
131
|
+
- lib/rails/generators/channel/templates/application_cable/connection.rb
|
132
132
|
- lib/rails/generators/channel/templates/channel.rb.tt
|
133
133
|
- lib/rails/generators/channel/templates/javascript/channel.js.tt
|
134
134
|
- lib/rails/generators/channel/templates/javascript/consumer.js.tt
|
@@ -140,10 +140,10 @@ licenses:
|
|
140
140
|
- MIT
|
141
141
|
metadata:
|
142
142
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
143
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
144
|
-
documentation_uri: https://api.rubyonrails.org/
|
143
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.0.alpha1/actioncable/CHANGELOG.md
|
144
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.0.alpha1/
|
145
145
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
146
|
-
source_code_uri: https://github.com/rails/rails/tree/
|
146
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/actioncable
|
147
147
|
post_install_message:
|
148
148
|
rdoc_options: []
|
149
149
|
require_paths:
|
@@ -152,14 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
152
|
requirements:
|
153
153
|
- - ">="
|
154
154
|
- !ruby/object:Gem::Version
|
155
|
-
version: 2.
|
155
|
+
version: 2.7.0
|
156
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
|
-
- - "
|
158
|
+
- - ">"
|
159
159
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
160
|
+
version: 1.3.1
|
161
161
|
requirements: []
|
162
|
-
rubygems_version: 3.1.
|
162
|
+
rubygems_version: 3.1.6
|
163
163
|
signing_key:
|
164
164
|
specification_version: 4
|
165
165
|
summary: WebSocket framework for Rails.
|