anycable-rails 0.5.5 → 0.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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