anycable 0.6.0 → 1.0.0.preview1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +93 -5
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +13 -6
  5. data/bin/anycable +1 -1
  6. data/bin/anycabled +30 -0
  7. data/lib/anycable.rb +8 -13
  8. data/lib/anycable/broadcast_adapters.rb +3 -3
  9. data/lib/anycable/broadcast_adapters/redis.rb +2 -2
  10. data/lib/anycable/cli.rb +16 -6
  11. data/lib/anycable/config.rb +10 -5
  12. data/lib/anycable/exceptions_handling.rb +13 -9
  13. data/lib/anycable/health_server.rb +2 -3
  14. data/lib/anycable/middleware.rb +3 -0
  15. data/lib/anycable/middleware_chain.rb +2 -2
  16. data/lib/anycable/middlewares/check_version.rb +24 -0
  17. data/lib/anycable/rpc.rb +76 -0
  18. data/lib/anycable/rpc/rpc_pb.rb +54 -39
  19. data/lib/anycable/rpc/rpc_services_pb.rb +4 -3
  20. data/lib/anycable/rpc_handler.rb +77 -24
  21. data/lib/anycable/rspec.rb +6 -0
  22. data/lib/anycable/rspec/rpc_command_context.rb +20 -0
  23. data/lib/anycable/rspec/rpc_stub_context.rb +13 -0
  24. data/lib/anycable/rspec/with_grpc_server.rb +15 -0
  25. data/lib/anycable/server.rb +4 -48
  26. data/lib/anycable/socket.rb +39 -2
  27. data/lib/anycable/version.rb +1 -1
  28. metadata +34 -72
  29. data/.github/ISSUE_TEMPLATE.md +0 -25
  30. data/.github/PULL_REQUEST_TEMPLATE.md +0 -31
  31. data/.gitignore +0 -40
  32. data/.hound.yml +0 -3
  33. data/.rubocop.yml +0 -71
  34. data/.travis.yml +0 -12
  35. data/Gemfile +0 -8
  36. data/Makefile +0 -5
  37. data/PITCHME.md +0 -139
  38. data/PITCHME.yaml +0 -1
  39. data/Rakefile +0 -8
  40. data/anycable.gemspec +0 -35
  41. data/assets/Memory3.png +0 -0
  42. data/assets/Memory5.png +0 -0
  43. data/assets/RTT3.png +0 -0
  44. data/assets/RTT5.png +0 -0
  45. data/assets/Scheme1.png +0 -0
  46. data/assets/Scheme2.png +0 -0
  47. data/assets/cpu_chart.gif +0 -0
  48. data/assets/cpu_chart2.gif +0 -0
  49. data/assets/evlms.png +0 -0
  50. data/benchmarks/.gitignore +0 -2
  51. data/benchmarks/2017-02-12.md +0 -308
  52. data/benchmarks/2018-03-04.md +0 -192
  53. data/benchmarks/2018-05-27-rpc-bench.md +0 -57
  54. data/benchmarks/2018-10-27.md +0 -181
  55. data/benchmarks/HowTo.md +0 -23
  56. data/benchmarks/ansible.cfg +0 -9
  57. data/benchmarks/assets/2018-10-27-action-cable-rss.png +0 -0
  58. data/benchmarks/assets/2018-10-27-action-cable-rtt.png +0 -0
  59. data/benchmarks/assets/2018-10-27-anycable-rss.png +0 -0
  60. data/benchmarks/assets/2018-10-27-anycable-rtt.png +0 -0
  61. data/benchmarks/assets/2018-10-27-async-rss.png +0 -0
  62. data/benchmarks/assets/2018-10-27-async-rtt.png +0 -0
  63. data/benchmarks/assets/2018-10-27-falcon-cable-rss.png +0 -0
  64. data/benchmarks/assets/2018-10-27-falcon-cable-rtt.png +0 -0
  65. data/benchmarks/assets/2018-10-27-iodine-cable-rss.png +0 -0
  66. data/benchmarks/assets/2018-10-27-iodine-cable-rtt.png +0 -0
  67. data/benchmarks/assets/2018-10-27-plezi-rss.png +0 -0
  68. data/benchmarks/assets/2018-10-27-plezi-rtt.png +0 -0
  69. data/benchmarks/bench.png +0 -0
  70. data/benchmarks/benchmark.yml +0 -69
  71. data/benchmarks/hosts +0 -5
  72. data/benchmarks/rtt_plot.py +0 -74
  73. data/benchmarks/rtt_plot_test.py +0 -16
  74. data/benchmarks/servers.yml +0 -58
  75. data/circle.yml +0 -8
  76. data/etc/bug_report_template.rb +0 -76
  77. data/lib/anycable/handler/capture_exceptions.rb +0 -39
  78. data/protos/rpc.proto +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9ae04f9598f3eff108b5370c1d173154bdab5d7e025a088a5b72375dc316db6
4
- data.tar.gz: 932eef1358398dd50d0347f7c16eadae2c3edd1ce431807c115dc3eed7480d5f
3
+ metadata.gz: 65d07fe802d850f89351ed8c054d2cba9c393b36f7a5aa318183362f09d53e58
4
+ data.tar.gz: b4167ba77ce930ddcb77a9e38d205215fb3ec085a93bfd3876f2bf8a5e669373
5
5
  SHA512:
6
- metadata.gz: 83a118f66c08b3555e5627973160d9f0c09c1796fb6f4f9b7157ed39be8f67cfdf735109d31b8e510b3ef4b6fa94427b9d178e37fb55edc416255763e190e99d
7
- data.tar.gz: 8df3faa61cbb9f6f36ca1f009842e5f14a1d68e775e2c670b952c61b20c564aad66807bd3c71f61e1895aa17953d365be90e2ca446fa275389c7ec8ad8d0f296
6
+ metadata.gz: 456af4dd28de6d32a8436ce8702ddb3ba5523b25b531bce8dac00c5bf6cd181e79c57e4d4a89d1a2c1ff3e21eda1108be3f023c65edcf1bbf5790594216ae971
7
+ data.tar.gz: b25fa2a291a6cd6bbf4734c9c59dcf991dead19c0e25c004ac696ec524e6de63bb5ea4251f8d06ce1d21699a44e178a7e445bfedcd4d70179535c6648ed67854
@@ -1,8 +1,95 @@
1
1
  # Change log
2
2
 
3
- ## master
3
+ ## 🚧 1.0.0 (_coming soon_)
4
4
 
5
- ## 0.6.0-dev
5
+ - **RPC schema has changed**. ([@palkan][])
6
+
7
+ Using `anycable-go` v1.x is required.
8
+
9
+ - **Ruby 2.5+ is required**. ([@palkan][])
10
+
11
+ - Added RPC proto version check. ([@palkan][])
12
+
13
+ Server must sent `protov` metadata with the supported versions (comma-separated list). If there is no matching version an exception is raised.
14
+
15
+ Current RPC proto version is **v1**.
16
+
17
+ - Added `request` support to channels. ([@palkan][])
18
+
19
+ Now you can access `request` object in channels, too (e.g., to read headers/cookies/URL/etc).
20
+
21
+ - Change default server address from `[::]:50051` to `127.0.0.1:50051`. ([@palkan][])
22
+
23
+ See [#71](https://github.com/anycable/anycable/pull/71).
24
+
25
+ ## 0.6.4 (2020-01-24)
26
+
27
+ - Fix Ruby 2.7 warnings. ([@palkan])
28
+
29
+ – Add `REMOTE_ADDR` socket env variable using a synthetic header passed from a websocket
30
+ server. ([@sponomarev][])
31
+
32
+ Recreating a request object in your custom connection factory using `Rack::Request` or
33
+ `ActionDispatch::Request` (already implemented in [anycable-rails](https://github.com/anycable/anycable-rails))
34
+ gives you an access to `request.ip` with the properly set IP address.
35
+
36
+ - Align socket env to be more compatibile with Rack Spec ([@sponomarev][])
37
+
38
+ Provide as much env details as possible to be able to reconstruct the full
39
+ request object in a custom connection factory.
40
+
41
+ ## 0.6.3 (2019-03-26)
42
+
43
+ - Relax `redis` gem version requirement. ([@palkan][])
44
+
45
+ Use the same restriction as Action Cable does (`>= 3`).
46
+
47
+ ## 0.6.2 (2019-03-15)
48
+
49
+ - Add GRPC service method name and message content to exception notifications ([@sponomarev][])
50
+
51
+ `Anycable.capture_exception` allows accessing GRPC service method name and message content
52
+ on which an exception was captured. It can be used for exceptions grouping in your tracker and
53
+ providing additional data to investigate a root of a problem.
54
+
55
+ Example:
56
+
57
+ ```ruby
58
+ AnyCable.capture_exception do |ex, method, message|
59
+ Honeybadger.notify(ex, component: "any_cable", action: method, params: message)
60
+ end
61
+ ```
62
+
63
+ Usage of a handler proc with just a single argument is preserved for the sake of compatibility.
64
+
65
+ - Add deprecation warning to default host usage ([@sponomarev][])
66
+
67
+ Exposing AnyCable publicly is considered to be harmful and planned to be changed
68
+ in future versions.
69
+
70
+ - Allow running the server as a detachable daemon ([@sponomarev][])
71
+
72
+ Server is fully managed by the binary itself.
73
+
74
+ ```
75
+ # Start anycable daemon
76
+ $ bundle exec anycabled start
77
+
78
+ # Pass cli options to anycable through daemon. Separate daemon options and anycable options with `--`
79
+ $ bundle exec anycabled start -- --rpc-host 127.0.0.1:31337
80
+
81
+ # Stop anycable daemon
82
+ $ bundle exec anycabled stop
83
+
84
+ # See more anycable daemon options
85
+ $ bundle exec anycabled
86
+ ```
87
+
88
+ ## 0.6.1 (2019-01-05)
89
+
90
+ - [Fix #63](https://github.com/anycable/anycable-rails/issues/63) Load `anyway_config` after application boot to make sure that all frameworks dependent functionality is loaded. ([@palkan][])
91
+
92
+ ## 0.6.0 (2018-11-15)
6
93
 
7
94
  ### Features
8
95
 
@@ -13,7 +100,7 @@ AnyCable allows you to use custom broadcasting adapters (Redis is used by defaul
13
100
  ```ruby
14
101
  # Specify by name (tries to load `AnyCable::BroadcastAdapters::MyAdapter` from
15
102
  # "anycable/broadcast_adapters/my_adapter")
16
- AnyCable.broadcast_adapter = :my_adapter, { option: "value" }
103
+ AnyCable.broadcast_adapter = :my_adapter, {option: "value"}
17
104
  # or provide an instance (should respond_to #broadcast)
18
105
  AnyCable.broadcast_adapter = MyAdapter.new
19
106
  ```
@@ -112,7 +199,7 @@ Minor fixes.
112
199
 
113
200
  - [#28](https://github.com/anycable/anycable/issues/28) Support arbitrary headers. ([@palkan][])
114
201
 
115
- Previously we hardcoded only "Cookie" header. Now we add all passed headers by WebSocket server to request env.
202
+ Previously we hardcoded only "Cookie" header. Now we add all passed headers by WebSocket server to request env.
116
203
 
117
204
  - [#27](https://github.com/anycable/anycable/issues/27) Add `error_msg` to RPC responses. ([@palkan][])
118
205
 
@@ -126,7 +213,7 @@ We provide `error_msg` only when request status is `ERROR`.
126
213
 
127
214
  - [#25](https://github.com/anycable/anycable/issues/25) Improve logging and exceptions handling. ([@palkan][])
128
215
 
129
- Default logger logs to STDOUT with `info` level by default but can be configured to log to file with
216
+ Default logger logs to STDOUT with `info` level by default but can be configured to log to file with
130
217
  any severity.
131
218
 
132
219
  GRPC logging is turned off by default (can be turned on through `log_grpc` configuration parameter).
@@ -193,3 +280,4 @@ Implement `Disconnect` handler, which invokes `Connection#disconnect` (along wit
193
280
  [@sadovnik]: https://github.com/sadovnik
194
281
  [@accessd]: https://github.com/accessd
195
282
  [@DarthSim]: https://github.com/DarthSim
283
+ [@sponomarev]: https://github.com/sponomarev
@@ -1,4 +1,4 @@
1
- Copyright 2017 palkan
1
+ Copyright 2017-2019 Vladimir Dementyev
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -9,15 +9,15 @@
9
9
 
10
10
  AnyCable allows you to use any WebSocket server (written in any language) as a replacement for your Ruby server (such as Faye, ActionCable, etc).
11
11
 
12
- AnyCable uses ActionCable protocol, so you can use ActionCable [JavaScript client](https://www.npmjs.com/package/actioncable) without any monkey-patching.
12
+ AnyCable uses the same protocol as ActionCable, so you can use its [JavaScript client](https://www.npmjs.com/package/actioncable) without any monkey-patching.
13
13
 
14
14
  <a href="https://evilmartians.com/">
15
15
  <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
16
16
 
17
17
  ## Requirements
18
18
 
19
- - Ruby >= 2.4
20
- - Redis (for brodcasting, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
19
+ - Ruby >= 2.5
20
+ - Redis (for broadcasting, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
21
21
 
22
22
  ## Usage
23
23
 
@@ -33,6 +33,8 @@ Check out our 📑 [Documentation](https://docs.anycable.io).
33
33
 
34
34
  ## Talks
35
35
 
36
+ - High-speed cables for Ruby, RubyConf 2018, [slides](https://speakerdeck.com/palkan/rubyconf-2018-high-speed-cables-for-ruby) and [video](https://www.youtube.com/watch?v=8XRcOZXOzV4) (EN)
37
+
36
38
  - One cable to rule them all, RubyKaigi 2018, [slides](https://speakerdeck.com/palkan/rubykaigi-2018-anycable-one-cable-to-rule-them-all) and [video](https://www.youtube.com/watch?v=jXCPuNICT8s) (EN)
37
39
 
38
40
  - Wroc_Love.rb 2018 [slides](https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-cables-cables-cables) and [video](https://www.youtube.com/watch?v=AUxFFOehiy0) (EN)
@@ -50,22 +52,27 @@ Check out our 📑 [Documentation](https://docs.anycable.io).
50
52
 
51
53
  - Install required GRPC gems:
52
54
 
53
- ```
55
+ ```sh
54
56
  gem install grpc
55
57
  gem install grpc-tools
56
58
  ```
57
59
 
58
60
  - Re-generate GRPC files (if necessary):
59
61
 
60
- ```
62
+ ```sh
61
63
  make
62
64
  ```
63
65
 
64
66
  ## Contributing
65
67
 
66
- Bug reports and pull requests are welcome on GitHub at https://github.com/anycable/anycable.
68
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable](https://github.com/anycable/anycable).
67
69
 
68
70
  Please, provide reproduction script (using [this template](https://github.com/anycable/anycable/blob/master/etc/bug_report_template.rb)) when submitting bugs if possible.
69
71
 
70
72
  ## License
73
+
71
74
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
75
+
76
+ ## Security Contact
77
+
78
+ To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative "../lib/anycable/cli"
3
+ require "anycable/cli"
4
4
 
5
5
  begin
6
6
  cli = AnyCable::CLI.new
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "anycable/cli"
4
+
5
+ begin
6
+ require "daemons"
7
+ rescue LoadError
8
+ raise <<~MSG
9
+ You need to add gem 'daemons' to your Gemfile if you want to use `anycabled`:
10
+
11
+ # Gemfile
12
+ gem "daemons", "~> 1.3", require: false
13
+ MSG
14
+ end
15
+
16
+ options = {
17
+ dir: "tmp/pids",
18
+ log_output: false
19
+ }
20
+
21
+ # Preserve current directory. We need it inside the server.
22
+ current_dir = Dir.pwd
23
+
24
+ # Clean ARGV from daemon command and args
25
+ _, _, args = Daemons::Controller.split_argv(ARGV)
26
+
27
+ Daemons.run_proc("anycable", options) do
28
+ Dir.chdir current_dir
29
+ AnyCable::CLI.new.run(args)
30
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "anycable/version"
4
- require "anycable/config"
5
4
  require "logger"
6
5
 
7
6
  require "anycable/exceptions_handling"
@@ -39,7 +38,12 @@ module AnyCable
39
38
  end
40
39
 
41
40
  def config
42
- @config ||= Config.new
41
+ @config ||= begin
42
+ # Load anyway_config as later as possible
43
+ # to make sure all framework-dependent patches are loaded
44
+ require "anycable/config"
45
+ Config.new
46
+ end
43
47
  end
44
48
 
45
49
  def configure
@@ -52,14 +56,6 @@ module AnyCable
52
56
  ExceptionsHandling << block
53
57
  end
54
58
 
55
- def error_handlers
56
- warn <<~DEPRECATION
57
- Using `AnyCable.error_handlers` is deprecated!
58
- Please, use `AnyCable.capture_exception` instead.
59
- DEPRECATION
60
- ExceptionsHandling
61
- end
62
-
63
59
  # Register a callback to be invoked before
64
60
  # the server starts
65
61
  def configure_server(&block)
@@ -99,8 +95,7 @@ module AnyCable
99
95
  attr_writer :middleware
100
96
  end
101
97
 
98
+ require "anycable/middlewares/check_version"
99
+
102
100
  self.middleware = MiddlewareChain.new
103
101
  end
104
-
105
- # Backward compatibility
106
- Anycable = AnyCable
@@ -17,16 +17,16 @@ module AnyCable
17
17
  # We couldn't require the adapter itself.
18
18
  if e.path == path_to_adapter
19
19
  raise e.class, "Couldn't load the '#{adapter}' broadcast adapter for AnyCable",
20
- e.backtrace
20
+ e.backtrace
21
21
  # Bubbled up from the adapter require.
22
22
  else
23
23
  raise e.class, "Error loading the '#{adapter}' broadcast adapter for AnyCable",
24
- e.backtrace
24
+ e.backtrace
25
25
  end
26
26
  end
27
27
  end
28
28
 
29
- BroadcastAdapters.const_get(adapter_class_name, false).new(options || {})
29
+ BroadcastAdapters.const_get(adapter_class_name, false).new(**(options || {}))
30
30
  end
31
31
  # rubocop: enable Metrics/AbcSize, Metrics/MethodLength
32
32
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- gem "redis", ">= 4.0"
3
+ gem "redis", ">= 3"
4
4
 
5
5
  require "redis"
6
6
  require "json"
@@ -34,7 +34,7 @@ module AnyCable
34
34
  def broadcast(stream, payload)
35
35
  redis_conn.publish(
36
36
  channel,
37
- { stream: stream, data: payload }.to_json
37
+ {stream: stream, data: payload}.to_json
38
38
  )
39
39
  end
40
40
  end
@@ -23,7 +23,7 @@ module AnyCable
23
23
  attr_reader :server, :health_server
24
24
 
25
25
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
26
- def run(args)
26
+ def run(args = {})
27
27
  @at_stop = []
28
28
 
29
29
  extra_options = parse_cli_options!(args)
@@ -34,13 +34,13 @@ module AnyCable
34
34
 
35
35
  parse_gem_options!(extra_options)
36
36
 
37
- logger.info "Starting AnyCable gRPC server (pid: #{Process.pid})"
37
+ configure_server!
38
+
39
+ logger.info "Starting AnyCable gRPC server (pid: #{Process.pid}, workers_num: #{config.rpc_pool_size})"
38
40
 
39
41
  print_versions!
40
42
 
41
- logger.info "Serving #{defined?(::Rails) ? 'Rails ' : ''}application from #{boot_file}"
42
-
43
- configure_server!
43
+ logger.info "Serving #{defined?(::Rails) ? "Rails " : ""}application from #{boot_file}"
44
44
 
45
45
  verify_connection_factory!
46
46
 
@@ -48,6 +48,8 @@ module AnyCable
48
48
 
49
49
  log_errors!
50
50
 
51
+ use_version_check! if config.version_check_enabled?
52
+
51
53
  @server = AnyCable::Server.new(
52
54
  host: config.rpc_host,
53
55
  **config.to_grpc_params,
@@ -124,7 +126,7 @@ module AnyCable
124
126
  end
125
127
 
126
128
  def print_versions!
127
- logger.info "AnyCable version: #{AnyCable::VERSION}"
129
+ logger.info "AnyCable version: #{AnyCable::VERSION} (proto_version: #{AnyCable::PROTO_VERSION})"
128
130
  logger.info "gRPC version: #{GRPC::VERSION}"
129
131
  end
130
132
 
@@ -162,6 +164,14 @@ module AnyCable
162
164
  AnyCable.server_callbacks.each(&:call)
163
165
  end
164
166
 
167
+ def use_version_check!
168
+ require "anycable/middlewares/check_version"
169
+
170
+ AnyCable.middleware.use(
171
+ AnyCable::Middlewares::CheckVersion.new(AnyCable::PROTO_VERSION)
172
+ )
173
+ end
174
+
165
175
  def start_health_server!
166
176
  @health_server = AnyCable::HealthServer.new(
167
177
  server,
@@ -10,8 +10,8 @@ module AnyCable
10
10
 
11
11
  attr_config(
12
12
  ### gRPC options
13
- rpc_host: "[::]:50051",
14
- # For defaults see https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/generic/rpc_server.rb#L162-L170
13
+ rpc_host: "127.0.0.1:50051",
14
+ # For defaults see https://github.com/grpc/grpc/blob/51f0d35509bcdaba572d422c4f856208162022de/src/ruby/lib/grpc/generic/rpc_server.rb#L186-L216
15
15
  rpc_pool_size: GRPC::RpcServer::DEFAULT_POOL_SIZE,
16
16
  rpc_max_waiting_requests: GRPC::RpcServer::DEFAULT_MAX_WAITING_REQUESTS,
17
17
  rpc_poll_period: GRPC::RpcServer::DEFAULT_POLL_PERIOD,
@@ -32,9 +32,14 @@ module AnyCable
32
32
 
33
33
  ### Health check options
34
34
  http_health_port: nil,
35
- http_health_path: "/health"
35
+ http_health_path: "/health",
36
+
37
+ ### Misc options
38
+ version_check_enabled: true
36
39
  )
37
40
 
41
+ alias version_check_enabled? version_check_enabled
42
+
38
43
  ignore_options :rpc_server_args
39
44
  flag_options :log_grpc, :debug
40
45
 
@@ -69,7 +74,7 @@ module AnyCable
69
74
 
70
75
  # Build Redis parameters
71
76
  def to_redis_params
72
- { url: redis_url }.tap do |params|
77
+ {url: redis_url}.tap do |params|
73
78
  next if redis_sentinels.nil?
74
79
 
75
80
  raise ArgumentError, "redis_sentinels must be an array; got #{redis_sentinels}" unless
@@ -100,7 +105,7 @@ module AnyCable
100
105
 
101
106
  raise ArgumentError, "Invalid Sentinel value: #{sentinel}" if matches.nil?
102
107
 
103
- { "host" => matches[1], "port" => matches[2].to_i }
108
+ {"host" => matches[1], "port" => matches[2].to_i}
104
109
  end
105
110
  end
106
111
  end
@@ -4,25 +4,29 @@ module AnyCable
4
4
  module ExceptionsHandling # :nodoc:
5
5
  class << self
6
6
  def add_handler(block)
7
- handlers << block
7
+ handlers << procify(block)
8
8
  end
9
9
 
10
10
  alias << add_handler
11
11
 
12
- def notify(exp)
12
+ def notify(exp, method_name, message)
13
13
  handlers.each do |handler|
14
- begin
15
- handler.call(exp)
16
- rescue StandardError => exp
17
- AnyCable.logger.error "!!! EXCEPTION HANDLER THREW AN ERROR !!!"
18
- AnyCable.logger.error exp
19
- AnyCable.logger.error exp.backtrace.join("\n") unless exp.backtrace.nil?
20
- end
14
+ handler.call(exp, method_name, message)
15
+ rescue => exp
16
+ AnyCable.logger.error "!!! EXCEPTION HANDLER THREW AN ERROR !!!"
17
+ AnyCable.logger.error exp
18
+ AnyCable.logger.error exp.backtrace.join("\n") unless exp.backtrace.nil?
21
19
  end
22
20
  end
23
21
 
24
22
  private
25
23
 
24
+ def procify(block)
25
+ return block unless block.lambda?
26
+
27
+ proc { |*args| block.call(*args.take(block.arity)) }
28
+ end
29
+
26
30
  def handlers
27
31
  @handlers ||= []
28
32
  end