anycable-rails 0.5.5 → 0.6.0.rc1

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +29 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +31 -0
  4. data/.rubocop.yml +24 -34
  5. data/CHANGELOG.md +31 -1
  6. data/README.md +47 -92
  7. data/Rakefile +7 -2
  8. data/anycable-rails.gemspec +3 -3
  9. data/lib/action_cable/subscription_adapter/any_cable.rb +23 -0
  10. data/lib/anycable/rails.rb +4 -4
  11. data/lib/anycable/rails/actioncable/channel.rb +8 -4
  12. data/lib/anycable/rails/actioncable/connection.rb +57 -23
  13. data/lib/anycable/rails/compatibility.rb +57 -0
  14. data/lib/anycable/rails/compatibility/rubocop.rb +28 -0
  15. data/lib/anycable/rails/compatibility/rubocop/config/default.yml +12 -0
  16. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb +50 -0
  17. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb +29 -0
  18. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/remote_disconnect.rb +31 -0
  19. data/lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb +100 -0
  20. data/lib/anycable/rails/config.rb +3 -2
  21. data/lib/anycable/rails/middlewares/executor.rb +21 -0
  22. data/lib/anycable/rails/middlewares/log_tagging.rb +21 -0
  23. data/lib/anycable/rails/railtie.rb +20 -27
  24. data/lib/anycable/rails/refinements/subscriptions.rb +1 -1
  25. data/lib/anycable/rails/version.rb +2 -2
  26. metadata +25 -19
  27. data/lib/anycable/rails/actioncable/server.rb +0 -14
  28. data/lib/anycable/rails/activerecord/release_connection.rb +0 -29
  29. data/lib/generators/anycable/USAGE +0 -7
  30. data/lib/generators/anycable/anycable_generator.rb +0 -16
  31. data/lib/generators/anycable/templates/anycable.yml +0 -41
  32. data/lib/generators/anycable/templates/script +0 -6
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Extend Anycable configuration with
3
+ # Extend AnyCable configuration with
4
4
  # `access_logs_disabled` options (defaults to true)
5
- Anycable::Config.attr_config access_logs_disabled: true
5
+ AnyCable::Config.attr_config access_logs_disabled: true
6
+ AnyCable::Config.ignore_options :access_logs_disabled
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCable
4
+ module Rails
5
+ module Middlewares
6
+ # Executor runs Rails executor for each call
7
+ # See https://guides.rubyonrails.org/v5.2.0/threading_and_code_execution.html#framework-behavior
8
+ class Executor < AnyCable::Middleware
9
+ attr_reader :executor
10
+
11
+ def initialize(executor)
12
+ @executor = executor
13
+ end
14
+
15
+ def call(*)
16
+ executor.wrap { yield }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCable
4
+ module Rails
5
+ module Middlewares
6
+ # Middleware to add `sid` (session ID) tag to logs.
7
+ #
8
+ # Session ID could be provided through gRPC metadata `sid` key.
9
+ #
10
+ # See https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md
11
+ class LogTagging < AnyCable::Middleware
12
+ def call(_request, call, _method)
13
+ sid = call.metadata["sid"]
14
+ return yield unless sid
15
+
16
+ AnyCable.logger.tagged("AnyCable sid=#{sid}") { yield }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,31 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Anycable
3
+ module AnyCable
4
4
  module Rails
5
- # Use this proxy to quack like a TaggedLoggerProxy
6
- class LoggerProxy
7
- def initialize(logger)
8
- @logger = logger
9
- end
10
-
11
- def add_tags(*_tags)
12
- @logger.warn "Tagged logger is not supported by AnyCable. Skip"
13
- end
14
-
15
- %i[debug info warn error fatal unknown].each do |severity|
16
- define_method(severity) do |message|
17
- @logger.send severity, message
18
- end
19
- end
20
- end
21
-
22
5
  class Railtie < ::Rails::Railtie # :nodoc:
23
- initializer "anycable.disable_action_cable_mount", before: "action_cable.routes" do |app|
6
+ initializer "anycable.disable_action_cable_mount", after: "action_cable.set_configs" do |app|
7
+ # Disable Action Cable when AnyCable adapter is used
8
+ next unless ::ActionCable.server.config.cable&.fetch("adapter", nil) == "any_cable"
9
+
24
10
  app.config.action_cable.mount_path = nil
25
11
  end
26
12
 
27
- initializer "anycable.logger", after: :initialize_logger do |_app|
28
- Anycable.logger = LoggerProxy.new(::Rails.logger)
13
+ initializer "anycable.logger", after: "action_cable.logger" do |_app|
14
+ AnyCable.logger = ActiveSupport::TaggedLogging.new(::ActionCable.server.config.logger)
29
15
 
30
16
  # Broadcast logs to STDOUT in development
31
17
  if ::Rails.env.development? &&
@@ -36,18 +22,25 @@ module Anycable
36
22
  console.level = ::Rails.logger.level
37
23
  ::Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
38
24
  end
39
- end
40
25
 
41
- initializer "anycable.release_connections" do |_app|
42
- ActiveSupport.on_load(:active_record) do
43
- require "anycable/rails/activerecord/release_connection"
44
- Anycable::RPCHandler.prepend Anycable::Rails::ActiveRecord::ReleaseConnection
26
+ # Add tagging middleware
27
+ if AnyCable.logger.respond_to?(:tagged)
28
+ require "anycable/rails/middlewares/log_tagging"
29
+
30
+ AnyCable.middleware.use(AnyCable::Rails::Middlewares::LogTagging)
45
31
  end
46
32
  end
47
33
 
34
+ initializer "anycable.executor" do |app|
35
+ require "anycable/rails/middlewares/executor"
36
+ # see https://github.com/rails/rails/pull/33469/files
37
+ executor = app.config.reload_classes_only_on_change ? app.reloader : app.executor
38
+ AnyCable.middleware.use(AnyCable::Rails::Middlewares::Executor.new(executor))
39
+ end
40
+
48
41
  initializer "anycable.connection_factory", after: "action_cable.set_configs" do |_app|
49
42
  ActiveSupport.on_load(:action_cable) do
50
- Anycable.connection_factory = connection_class.call
43
+ AnyCable.connection_factory = connection_class.call
51
44
  end
52
45
  end
53
46
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Anycable
3
+ module AnyCable
4
4
  module Refinements
5
5
  module Subscriptions # :nodoc:
6
6
  refine ActionCable::Connection::Subscriptions do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Anycable
3
+ module AnyCable
4
4
  module Rails
5
- VERSION = "0.5.5"
5
+ VERSION = "0.6.0.rc1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-28 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: anycable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.0
33
+ version: 0.6.0.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.5.0
40
+ version: 0.6.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -81,19 +81,19 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.4'
83
83
  - !ruby/object:Gem::Dependency
84
- name: ammeter
84
+ name: sqlite3
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '1.1'
89
+ version: '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: '1.1'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +143,8 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - ".github/ISSUE_TEMPLATE.md"
147
+ - ".github/PULL_REQUEST_TEMPLATE.md"
146
148
  - ".gitignore"
147
149
  - ".hound.yml"
148
150
  - ".rubocop.yml"
@@ -158,20 +160,24 @@ files:
158
160
  - circle.yml
159
161
  - gemfiles/rails5.gemfile
160
162
  - gemfiles/railsmaster.gemfile
163
+ - lib/action_cable/subscription_adapter/any_cable.rb
161
164
  - lib/anycable-rails.rb
162
165
  - lib/anycable/rails.rb
163
166
  - lib/anycable/rails/actioncable/channel.rb
164
167
  - lib/anycable/rails/actioncable/connection.rb
165
- - lib/anycable/rails/actioncable/server.rb
166
- - lib/anycable/rails/activerecord/release_connection.rb
168
+ - lib/anycable/rails/compatibility.rb
169
+ - lib/anycable/rails/compatibility/rubocop.rb
170
+ - lib/anycable/rails/compatibility/rubocop/config/default.yml
171
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb
172
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/periodical_timers.rb
173
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/remote_disconnect.rb
174
+ - lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb
167
175
  - lib/anycable/rails/config.rb
176
+ - lib/anycable/rails/middlewares/executor.rb
177
+ - lib/anycable/rails/middlewares/log_tagging.rb
168
178
  - lib/anycable/rails/railtie.rb
169
179
  - lib/anycable/rails/refinements/subscriptions.rb
170
180
  - lib/anycable/rails/version.rb
171
- - lib/generators/anycable/USAGE
172
- - lib/generators/anycable/anycable_generator.rb
173
- - lib/generators/anycable/templates/anycable.yml
174
- - lib/generators/anycable/templates/script
175
181
  homepage: http://github.com/anycable/anycable-rails
176
182
  licenses:
177
183
  - MIT
@@ -187,9 +193,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
193
  version: '0'
188
194
  required_rubygems_version: !ruby/object:Gem::Requirement
189
195
  requirements:
190
- - - ">="
196
+ - - ">"
191
197
  - !ruby/object:Gem::Version
192
- version: '0'
198
+ version: 1.3.1
193
199
  requirements: []
194
200
  rubyforge_project:
195
201
  rubygems_version: 2.7.7
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "action_cable/server/base"
4
-
5
- module ActionCable
6
- module Server
7
- # Override pubsub for ActionCable
8
- class Base
9
- def pubsub
10
- Anycable.pubsub
11
- end
12
- end
13
- end
14
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Anycable
4
- module Rails
5
- module ActiveRecord
6
- # Release ActiveRecord connection after every call (if any)
7
- module ReleaseConnection
8
- def connect(*)
9
- wrap_release_connection { super }
10
- end
11
-
12
- def disconnect(*)
13
- wrap_release_connection { super }
14
- end
15
-
16
- def command(*)
17
- wrap_release_connection { super }
18
- end
19
-
20
- def wrap_release_connection
21
- res = yield
22
- ::ActiveRecord::Base.connection_pool.release_connection if
23
- ::ActiveRecord::Base.connection_pool.active_connection?
24
- res
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,7 +0,0 @@
1
- Description:
2
- Generates Anycable executable
3
-
4
- Examples:
5
- rails generate anycable
6
-
7
- This will generate Anycable executable
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails/generators/base"
4
-
5
- class AnycableGenerator < Rails::Generators::Base # :nodoc:
6
- source_root File.expand_path('templates', __dir__)
7
-
8
- def create_executable_file
9
- template "script", "bin/anycable"
10
- chmod "bin/anycable", 0o755
11
- end
12
-
13
- def add_anycable_config
14
- template 'anycable.yml', 'config/anycable.yml'
15
- end
16
- end
@@ -1,41 +0,0 @@
1
- # grpс server settings, anycable grpc server will listen
2
- # websocket server at given host:port, usually Anycable server runs locally to ws server
3
- # MUST BE in sync with ws-server setting -rpc=0.0.0.0:50051
4
- # rpc_host: "localhost:50051"
5
-
6
- # redis url
7
- # MUST BE in sync with ws-server setting -redis=redis://localhost:6379/5
8
- # REM: Redis PubSub system doesn't use the database part of URI
9
- # redis_url: "redis://localhost:6379/5"
10
-
11
- # redis_sentinels:
12
- # - { host: 'localhost', port: 26379 }
13
- # - { host: 'redis-1-2', port: 26379 }
14
- # - { host: 'redis-1-3', port: 26379 }
15
-
16
- # anycable use single pubsub queue, this is queue name
17
- # MUST BE in sync with ws-server setting -redis_channel=__anycable__
18
- # redis_channel: "__anycable__",
19
-
20
- #---------- ENVIRONMENT VARIABLES ----------
21
- # since Anycable config based on anyway_config (https://github.com/palkan/anyway_config), all Anycable settings,
22
- # can be set or overridden through corresponding Environment variable.
23
- # Ex: rpc_host is overridden by ANYCABLE_RPC_HOST, redis_url by ANYCABLE_REDIS_URL e.t.c Look in anyway_config for more details
24
-
25
- default: &default
26
- rpc_host: "localhost:50051"
27
- log_grpc: false
28
- log_file: nil
29
- debug: false # Shortcut to enable GRPC logging and debug level
30
- log_level: info
31
- redis_channel: "__anycable__"
32
- redis_sentinels: []
33
-
34
-
35
- production:
36
- <<: *default
37
- redis_url: "redis://localhost:6379/1"
38
-
39
- development:
40
- <<: *default
41
- redis_url: "redis://localhost:6379/2"
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require ::File.expand_path('../../config/environment', __FILE__)
5
-
6
- Anycable::Server.start