Giter VIP home page Giter VIP logo

anycable-rails's Introduction

Gem Version Build Documentation

AnyCable Rails

AnyCable allows you to use any WebSocket server (written in any language) as a replacement for built-in Rails Action Cable server.

With AnyCable you can use channels, client-side JS, broadcasting - (almost) all that you can do with Action Cable.

You can even use Action Cable in development and not be afraid of compatibility issues.

💾 Example Application

📑 Documentation.

AnyCable Pro has been launched 🚀

Sponsored by Evil Martians

Requirements

  • Ruby >= 2.6
  • Rails >= 6.0 (Rails 5.1 could work but we're no longer enforce compatibility on CI)
  • Redis (see other options for broadcasting)

Usage

Add anycable-rails gem to your Gemfile:

gem "anycable-rails"

# when using Redis broadcast adapter
gem "redis", ">= 4.0"

Interactive set up

After the gem was installed, you can run an interactive wizard to configure your Rails application for using with AnyCable by running a generator:

bundle exec rails g anycable:setup

Manual set up

Specify AnyCable subscription adapter for Action Cable:

# config/cable.yml
development:
  adapter: any_cable # or anycable

production:
  adapter: any_cable

and specify AnyCable WebSocket server URL:

# For development it's likely the localhost

# config/environments/development.rb
config.action_cable.url = "ws://localhost:8080/cable"

# For production it's likely to have a sub-domain and secure connection

# config/environments/production.rb
config.action_cable.url = "wss://ws.example.com/cable"

Then, run AnyCable RPC server:

$ bundle exec anycable

# don't forget to provide Rails env

$ RAILS_ENV=production bundle exec anycable

And, finally, run AnyCable WebSocket server, e.g. anycable-go:

anycable-go --host=localhost --port=8080

See documentation for more information on AnyCable + Rails usage.

Action Cable Compatibility

See documentation.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/anycable/anycable-rails.

License

The gem is available as open source under the terms of the MIT License.

Security Contact

To report a security vulnerability, please contact us at [email protected]. We will coordinate the fix and disclosure.

anycable-rails's People

Contributors

bibendi avatar depfu[bot] avatar dmitrytsepelev avatar envek avatar ericmatte avatar iuri-gg avatar jonduarte avatar nerzh avatar palkan avatar sespindola avatar sponomarev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

anycable-rails's Issues

devise / warden emulation or support

I don't think that its must be a feature for anycable-rails, since its not anycable-devise %).

May be short attention notice for all middleware unability since it's gRPC service,
and just an example in wiki on how to emulate warden middleware and activate devise.

Sending authenticate token

Hi, now I'm trying to use anycable-go on heroku.
I referred this information and I succeeded to deploy both of Websocket server and Rails Server.

but I want authenticate WebSocket subscription with each user's token. like this:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    protected
      def find_verified_user
        if current_user = User.find_by(token:  request.headers[:token])
          current_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

Can I send token to server and use it in this case?

Cookies not working

I'm using Rails 5.1.4 and Anycable-Go 0.5.0

I have this code on my Gemfile

...
gem 'anycable-rails'
...

This on my application.rb

require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Chatstesting
  class Application < Rails::Application

    config.generators do |g|
      g.test_framework :rspec,
        fixtures: true,
        view_specs: true,
        helper_specs: true,
        routing_specs: true,
        controller_specs: true,
        request_specs: true
      g.fixture_replacement :factory_girl, dir: "spec/factories"
      g.template_engine :erb
    end
    config.time_zone = 'America/La_Paz'
    config.active_record.default_timezone = :local # Or :utc

    config.action_cable.url = "ws://0.0.0.0:3334/cable"
    config.action_cable.mount_path = "ws://0.0.0.0:3334/cable"

    # config.paths.add File.join('app/controllers', 'api'), glob: File.join('**', '*.rb')
    # config.autoload_paths += Dir[Rails.root.join('app/controllers', 'api', '*')]

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.
  end
end

This on my environment.rb

# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!

My cookie var is empty when I tried to connect

# connection.rb
def connect
  self.current_user = cookies[:username]
end

# sessions_controller.rb
def create
...
cookies[:username] = { value: @username, domain: :all }
...
end

I don't know what to do. Help me please

Handle multiple subscriptions to the same channel in a single connection

Tell us about your environment

Ruby version: 2.5.1

Rails version: 5.2.3

anycable gem version: 0.6.3

anycable-rails gem version: 0.6.4

grpc gem version: 1.22

What did you do?

As a client, I subscribed multiple times to the same channel in a single connection.

What did you expect to happen?

I expected Anycable to work like ActionCable by keeping only one subscription for the same connection so that I would receive each streamed message only once.

What actually happened?

The duplicated subscriptions make Anycable sending the same message multiple times through the same connection. As a consequence, the client may either react to the same event multiple times or handle the duplications by itself.

Notes

  • I am sorry if this is not the proper repository for this issue. Let me know if it is not =)
  • If this is the desired behavior, IMHO Anycable could at least offer a configuration option to avoid duplicated subscriptions.

ArgumentError: wrong number of arguments (given 2, expected 1) when trying to connect

Hello

I'm having troubles starting my anycable server. It produces this error when calling createConsumer on client side.

Rails -- Exception: ArgumentError: wrong number of arguments (given 2, expected 1)#12/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/anycable-rails-0.6.1/lib/anycable/rails/actioncable/connection.rb:34:in initialize'#012/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/actioncable-5.1.7/lib/action_cable/server/base.rb:28:in new'#12/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/actioncable-5.1.7/lib/action_cable/server/base.rb:28:in call'#012/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/actionpack-5.1.7/lib/action_dispatch/routing/mapper.rb:17:in block in class:Constraints'#12/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/actionpack-5.1.7/lib/action_dispatch/routing/mapper.rb:46:in serve'#012/opt/mdrevccm3_staging/shared/bundle/ruby/2.6.0/gems/actionpack-5.1.7/lib/action_dispatch/journey/router.rb:50:in block in serve'#12/opt/mdrevccm3_staging/shared/bundle/ruby/

printing: Rails.logger.info ActionCable.server.pubsub

Rails -- #ActionCable::SubscriptionAdapter::AnyCable:0x0000000005943a18

printing: Rails.logger.info AnyCable.broadcast_adapter.channel

Rails -- anycable-staging

My anycable.yml

staging:
  rpc_host: "0.0.0.0:50052"
  redis_url: "redis://localhost:6379"
  redis_channel: "anycable-staging"
  access_logs_disabled: false
  debug: true

My cable.yml

staging:
  adapter: any_cable

My config/environments/staging.rb

  config.action_cable.allowed_request_origins = [/http:\/\/*/, /https:\/\/*/]
  config.action_cable.url = "wss://my_staging_url.com/cable"

The commands I use to start anycable:

RAILS_ENV=staging ANYCABLE_DEBUG=1 bundle exec anycable --redis-channel=anycable-staging --rpc-host="[::]:50052"
ANYCABLE_DEBUG=1 bin/anycable-go --rpc_host=0.0.0.0:50052 --headers=cookie,x-api-token --redis_url=redis://localhost:6379 --redis_channel=anycable-staging --host=localhost --port=3335

ActionCable -- Starting AnyCable gRPC server (pid: 8957)
ActionCable -- AnyCable version: 0.6.0
ActionCable -- gRPC version: 1.19.0
ActionCable -- Serving Rails application from ./config/environment.rb
ActionCable -- handling /anycable.RPC/Connect with #<Method: AnyCable::RPCHandler(AnyCable::Handler::CaptureExceptions)#connect>
ActionCable -- handling /anycable.RPC/Command with #<Method: AnyCable::RPCHandler(AnyCable::Handler::CaptureExceptions)#command>
ActionCable -- handling /anycable.RPC/Disconnect with #<Method: AnyCable::RPCHandler(AnyCable::Handler::CaptureExceptions)#disconnect>
ActionCable -- handling /grpc.health.v1.Health/Check with #<Method: Grpc::Health::Checker#check>
ActionCable -- Broadcasting Redis channel: anycable-staging
ActionCable -- RPC server is starting...
ActionCable -- RPC server is listening on [::]:50052
DEBUG 2019-04-10T10:31:54.842Z context=main 🔧 🔧 🔧 Debug mode is on 🔧 🔧 🔧
  INFO 2019-04-10T10:31:54.842Z context=main Starting AnyCable v0.6.0 (pid: 9044)
 DEBUG 2019-04-10T10:31:54.843Z context=disconnector Calls rate: 10ms
  INFO 2019-04-10T10:31:54.843Z context=main Handle WebSocket connections at /cable
  INFO 2019-04-10T10:31:54.843Z context=http Starting HTTP server at localhost:3335
  INFO 2019-04-10T10:31:54.843Z context=pubsub Subscribed to Redis channel: anycable-staging

  INFO 2019-04-10T10:31:54.845Z context=rpc RPC pool initialized: 0.0.0.0:50052

Tell us about your environment

Ruby version: 2.6.2

Rails version: 5.1.7

anycable gem version: 0.6.0

anycable-rails gem version: 0.6.1

grpc gem version: 1.19.0

I have multiple environments running on the same machine with exactly the same code.
I used to have two of them (lets call them dev and dev2) running Anycable without a problem. Now I disabled dev2 and tried to enable Anycable on staging but I'm having this error.

Thanks in advance for helping us so promptly.

anycable.yml or cable.yml

Hello, my question is simple, do I use only anycable.yml or cable.yml or should I use both files? Thank you

#anycable.yml
default:&default
rpc_host: "localhost:50051"
log_grpc: false
log_file: nil
debug: false # Shortcut to enable GRPC logging and debug level
log_level: info
redis_channel: "anycable"
redis_url: "redis://localhost:6379"
redis_sentinels: []
development:
<<: *default
test:
<<: *default
production:
<<: *default`

#cable.yml
development:
adapter: redis
url: redis://localhost:6379/1
test:
adapter: async
production:
adapter: any_cable
url: redis://localhost:6379
channel_prefix: anycable

Implement undelivered messages

I want to implement something like whatsapp message, when you are not connected and you are connected again your message is arrived. but for that I implement after_subscribe the callback method forwading_queues than is executed after subscription channel. The problem is when there was some disconnection from client, and quickly he is connected again the method forwading_queues is executed but no send broadcast, I think that is because the old connection is active yet and the broadcast is send to old connection, because sometimes after the server said THE USER WAS DISCONNECTED but the broadcast_to was already executed in the method forwading_queues

class UserChannel < ApplicationCable::Channel
 after_subscribe :forwading_queues
 def subscribed
  stream_for current_user
 end

 def forwading_queues
  UserChannel.broadcast_to current_user, {message: 'You are back!'}
 end
end

Do you know what is happening here ?

Use Rails.logger as default Anycable.logger

We should consider using Rails.logger as the default Anycable.logger.

Currently, we use Rails.logger within Connection/Channel and Anycable.logger everywhere else.

This can be done through the engine's initilializer.

Reduce gem weight

Anycable is a great library, but it is using quite a lot of memory.

Tell us about your environment

Ruby version:
2.6
Rails version:
5.2
anycable gem version:
0.6.3
anycable-rails gem version:
0.6.4

What did you do?

Installed the derailed_benchmarks gem, and then ran the benchmarks.

bundle exec derailed bundle:mem

What actually happened?

 anycable-rails: 4.5625 MiB
    anycable/rails: 4.5586 MiB
      anycable: 3.4219 MiB
        anycable/server: 2.2656 MiB
          anycable/health_server: 1.7969 MiB

Errors in log files

Tell us about your environment

Ruby version:
2.5.1

Rails version:
5.2.2

anycable gem version:
0.6.1

anycable-rails gem version:
0.6.2

grpc gem version:
1.18.0

What happened?

We've been running anycable happily in production for a few days now. Today we went to deploy our rails app and found the partition with our rails log file had run out of disk space. On investigation our rails log had ballooned to 26GB cause by this log entry:

I, [2019-02-09T02:36:47.888116 #17304]  INFO -- : [AnyCable sid=RtYAn2no_65qw9Pj83lp8F] [ActionCable] [8777] SessionChannel is transmitting the subscription confirmati
on
E, [2019-02-09T02:36:48.280051 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280128 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280159 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280186 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280212 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280236 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280302 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280327 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
E, [2019-02-09T02:36:48.280350 #17304] ERROR -- : Errno::EMFILE: Too many open files - accept(2)
        /usr/lib/ruby/2.5.0/socket.rb:1313:in `__accept_nonblock'
...

The Errno::EMFILE: Too many open files is repeated millions of times.

We have anycable-go running on 1 server, then an AWS network load balancer facilitating gRPC traffic to two application servers running the anycable gems. Both application servers saw the errors at a similar time, however 1 server only created a 3GB log file where as the other generated a 26GB log file and saw many times more of these errors.

I'm assuming this is to do with the anycable gem(s) so I'm posting here to get some help with diagnosing what the problem is. Thanks

Anycable Rails Executable Not Handling (or Displaying) Errors

Hi,
I'm loving working with Anycable, and it's quite simple to get set up and running.
I'm running into an issue, however, whenever there's an exception in my Rails app. More precisely, exceptions are not reported anywhere in Anycable. I have debug enabled in the anycable.yml file, and I even went so far as to modify the Anycable::Handler::ExceptionsHandling module to see if the errors weren't even being printed. If I simulate any sort of error, even just calling non-existent methods, there is no log output at all. If I add a non-existent method call to the middle of a method in my websocket channel and then call .perform for the encapsulating method, the method stops executing without any message of any sort.
Obviously, this is an issue as I want to catch errors with a reporting system so I can be notified of them on production.
Any thoughts, including how I may have misconfigured this or if I am overlooking something are appreciated.

Tagged logger is broken in Rails.

I am getting this

undefined method `add_tags' for #<ActiveSupport::Logger:0x000000047b0940>

when using tagged loger in application_cable/connection.rb file
When this is commented out like this

    def connect
      self.current_user = find_verified_user
      #logger.add_tags 'ActionCable', current_user.email
    end

problem disappears and I am able to connect without any problems.
(Getting "Auth failed" with tagged logger from anycable-go websocket server)

incompatible with dotenv

Hello,

Whenever I convert my anycable.yml into using dotenv, it breaks.

This configuration of anycable.yml DOES work.

production:
rpc_host: 0.0.0.0:50051
redis_url: redis://redis:6379/0
redis_channel: anycable

however this configuration DOES NOT work.

<%= ENV.fetch('RAILS_ENV') %>:
rpc_host: <%= ENV.fetch('RPC_HOST') %>
redis_url: <%= ENV.fetch('REDIS_FULL_URL') %>
redis_channel: anycable

here are the applicable environment variables (exact same values):
- name: RAILS_ENV
value: production
- name: RPC_HOST
value: 0.0.0.0:50051
- name: REDIS_FULL_URL
value: redis://redis:6379/0
- name: REDIS_CHANNEL
value: anycable

and the logs for the anycable service (using the default image from dockerhub):

Running websocket server on 0.0.0.0:8080 at /cable
2017/11/21 21:49:52 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp 10.0.0.232:50051: getsockopt: connection refused"; Reconnecting to {"vcbe-ws:50051" }
2017/11/21 21:49:52 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp 10.0.0.232:50051: getsockopt: connection refused"; Reconnecting to {"vcbe-ws:50051" }

If you're wondering what "vcbe-ws:50051" is, it's the name of a service that points to the grpc host, this whole thing is running on my minikube cluster at the moment. The exact replica is also running on our alpha kubernetes cluster. Dotenv works with all other configuration including cable.yml which looks like the following:

<%= ENV.fetch('RAILS_ENV') %>:
:url: <%= ENV.fetch('REDIS_URL') %>
:port: <%= ENV.fetch('REDIS_PORT') %>
:db: 0
:adapter: redis
:namespace: cache

Everything else on the environment stays exactly the same. The only thing that causes it to break is when I switch to have anycable.yml pull its values from environmental variables.

Thank you :)

Add static and runtime compatibility check

We need a way to help detect compatibility issues as fast as possible.

I propose to add two different types of checks: dynamic (runtime) and static.

Dynamic Checks

Dynamic checks are monkey-patches which raise exceptions (Anycable::CompatibilityError) when AnyCable-incompatible code is called (we already have one such check here).

The idea is to extract all the checks (from the compatibility table) to a separate module (Anycable::Compatibility) and make it optional (with a recommendation to require it in "development" and "test" envs):

require "anycable/rails/compatibility"

NOTE: when loading Compatibility checks we must not load other AnyCable code and Action Cable patches (thus Compatibility shouldn't break compatible Action Cable code).

Unfortunately, tracking instance variables usage in Channels/Connections is not as easy as tracking methods calls (though we can compare instance_variables around some methods calls).

Static Analysis

Another approach to prevent compatibility issues is to create custom RuboCop cops:

  • AnyCable/StreamCallbacks
  • AnyCable/RemoteDisconnect
  • AnyCable/PeriodicalTimers
  • AnyCable/InstanceVars

And then in .rubocop.yml:

- require: "anycable/rails/compatibility/cops"
...

Or rubocop -r "anycable/rails/compatibility/cops".

The default configuration for these cops should have Include directive with "channels/**/*.rb" value.

NOTE: there is no RuboCop API for adding configurations yet. Here is an example of adding a default configuration for custom cops.

Figure out how to deal with a built-in Action Cable server

We got a bunch of issue related to clients trying to connect to the built-in Action Cable server instead of the AnyCable one (like ArgumentError: wrong number of arguments (given 2, expected 1) when trying to connect) (see #88, #22).

Looks like our current mechanism of disabling Action Cable server has problems (see

initializer "anycable.disable_action_cable_mount", after: "action_cable.set_configs" do |app|
# Disable Action Cable default route when AnyCable adapter is used
adapter = ::ActionCable.server.config.cable&.fetch("adapter", nil)
next unless AnyCable::Rails.compatible_adapter?(adapter)
app.config.action_cable.mount_path = nil
end
).

And it definitely doesn't work when mount ActionCable.server => ... is explicit in routes.rb.

The idea is, in addition to the existent hack (which should be fixed/improved), print a warning if Action Cable server has been mounted into the application stack and/or raise a meaningful exception when client tries to connect to the Action Cable server.

How to stream_from channels?

I have a StatusChannel and I get this Already Subscribed to {"channel":"StatusChannel","shop_id":3} in anycable-go logs showing its already connected.

Then, on rails log, it seems to stuck here StatusChannel is transmitting the subscription confirmation. If I use normal action cable, i get this message StatusChannel is streaming from somechannel after the previous message. I'm not sure why it doesnt stream when using anycable.

Error while establishing connection

Hello!
I've used this gem some time ago, and I really love it! But now, after fresh install of this gem and anycable-go server, I'm getting strange error when I want to connect to server:

[2017-06-26T09:59:19.578424 #15951] FATAL -- : [e9631f7b-6a54-4eee-85aa-013b68c9e31d] **ArgumentError (wrong number of arguments (given 2, expected 1)):**
F, [2017-06-26T09:59:19.578604 #15951] FATAL -- : [e9631f7b-6a54-4eee-85aa-013b68c9e31d]   
F, [2017-06-26T09:59:19.578794 #15951] FATAL -- : [e9631f7b-6a54-4eee-85aa-013b68c9e31d] anycable-rails (0.4.4) lib/anycable/rails/actioncable/connection.rb:28:in `initialize'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actioncable (5.0.4) lib/action_cable/server/base.rb:28:in `new'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actioncable (5.0.4) lib/action_cable/server/base.rb:28:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/routing/mapper.rb:17:in `block in <class:Constraints>'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/routing/mapper.rb:46:in `serve'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/journey/router.rb:39:in `block in serve'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/journey/router.rb:26:in `each'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/journey/router.rb:26:in `serve'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/routing/route_set.rb:725:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack-pjax (1.0.0) lib/rack/pjax.rb:12:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] remotipart (1.3.1) lib/remotipart/middleware.rb:32:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] warden (1.2.7) lib/warden/manager.rb:35:in `catch'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] warden (1.2.7) lib/warden/manager.rb:35:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/etag.rb:25:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/conditional_get.rb:25:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/head.rb:12:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/cookies.rb:613:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/callbacks.rb:38:in `block in call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/callbacks.rb:97:in `__run_callbacks__'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/callbacks.rb:750:in `_run_call_callbacks'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/callbacks.rb:90:in `run_callbacks'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/callbacks.rb:36:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/debug_exceptions.rb:49:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] railties (5.0.4) lib/rails/rack/logger.rb:36:in `call_app'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] railties (5.0.4) lib/rails/rack/logger.rb:24:in `block in call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/tagged_logging.rb:69:in `block in tagged'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/tagged_logging.rb:26:in `tagged'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/tagged_logging.rb:69:in `tagged'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] railties (5.0.4) lib/rails/rack/logger.rb:24:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/request_id.rb:24:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/method_override.rb:22:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/runtime.rb:22:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] activesupport (5.0.4) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] actionpack (5.0.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] railties (5.0.4) lib/rails/engine.rb:522:in `call'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] unicorn (5.3.0) lib/unicorn/http_server.rb:606:in `process_client'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] unicorn (5.3.0) lib/unicorn/http_server.rb:702:in `worker_loop'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] unicorn (5.3.0) lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] unicorn (5.3.0) lib/unicorn/http_server.rb:142:in `start'
[e9631f7b-6a54-4eee-85aa-013b68c9e31d] unicorn (5.3.0) bin/unicorn:126:in `<top (required)>'

Any suggestions? What additional information I need to provide?

failover support

Are there any issues with having multiple anycable-go apps running on separate boxes for failover?

Have you looked into adding redis-sentinel support in case redis needs to failover.

Since the grpc server will contain business logic it will need restarting. I could see using haproxy to round robin on the grpc servers from the anycable-go box.

ApplicationCable::Connection has been removed from the module tree but is still active

Ruby version: 2.5.1

Rails version: 5.2.2

anycable gem version: 0.6.1

anycable-rails gem version: 0.6.2

grpc gem version: grpc-1.18.0-universal-darwin

in Dev mode, when i leave it for a few minutes, these error coming up:

13:27:42 cable.1              | [AnyCable sid=WlNSBtRTBwb90dwd_GxnoG] A copy of ApplicationCable::Connection has been removed from the module tree but is still active!:
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.2/lib/active_support/dependencies.rb:495:in `load_missing_constant'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:58:in `block in load_missing_constant'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:16:in `allow_bootsnap_retry'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:57:in `load_missing_constant'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.2/lib/active_support/dependencies.rb:195:in `const_missing'
13:27:42 cable.1              | /Users/sen/code/apps/beachpricex/app/channels/application_cable/connection.rb:47:in `decoded_auth_token'
13:27:42 cable.1              | /Users/sen/code/apps/beachpricex/app/channels/application_cable/connection.rb:23:in `authorize_cable_request'
13:27:42 cable.1              | /Users/sen/code/apps/beachpricex/app/channels/application_cable/connection.rb:9:in `connect'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-rails-0.6.2/lib/anycable/rails/actioncable/connection.rb:54:in `handle_open'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-0.6.1/lib/anycable/rpc_handler.rb:24:in `connect'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-0.6.1/lib/anycable/handler/capture_exceptions.rb:22:in `block in connect'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-0.6.1/lib/anycable/handler/capture_exceptions.rb:28:in `capture_exceptions'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-0.6.1/lib/anycable/handler/capture_exceptions.rb:22:in `connect'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/grpc-1.18.0-universal-darwin/src/ruby/lib/grpc/generic/rpc_desc.rb:60:in `call'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/grpc-1.18.0-universal-darwin/src/ruby/lib/grpc/generic/rpc_desc.rb:60:in `block in handle_request_response'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/grpc-1.18.0-universal-darwin/src/ruby/lib/grpc/generic/interceptors.rb:178:in `block (2 levels) in intercept!'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/grpc-1.18.0-universal-darwin/src/ruby/lib/grpc/generic/interceptors.rb:181:in `block in intercept!'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-0.6.1/lib/anycable/middleware.rb:11:in `block in request_response'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/anycable-rails-0.6.2/lib/anycable/rails/middlewares/log_tagging.rb:16:in `block in call'
13:27:42 cable.1              | /Users/sen/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.2/lib/active_support/tagged_logging.rb:71:in `block in tagged'

this is strange.

AnyCable CLI игнорирует config/anycable.yml, config/secrets.yml

Доброго времени суток.

Tell us about your environment

Ruby version:
ruby-2.5.3

Rails version:
5.2.2

anycable gem version:
0.6.0

anycable-rails gem version:
0.6.1

grpc gem version:
1.17.0

What did you do?

Обновил anycable-rails с 0.5.5 до 0.6.1

What did you expect to happen?

bundle exec anycable должен читать и использовать config/anycable.yml

What actually happened?

config/anycable.yml игнорируется

Что происходит:
anyway_config загружается раньше rails и https://github.com/palkan/anyway_config/blob/master/lib/anyway.rb#L6 игнорируется

патч обезьяны:
В Gemfile добавить gem 'anyway_config', '~> 1.4.1', require: ['anyway', 'anyway/rails/config']

Option to disable logging to STDOUT in development

When using rails console in the development environment with this gem it will force logs to output to STDOUT as seen here:

# Broadcast logs to STDOUT in development
if ::Rails.env.development? &&
!ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, STDOUT) &&
!defined?(::Rails::Server)
console = ActiveSupport::Logger.new(STDOUT)
console.formatter = ::Rails.logger.formatter
console.level = ::Rails.logger.level
::Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
end

Ideally, I wouldn't want this gem to alter my Rails logger. Could you add an option to disable this feature or suggest a simple way to disable it? Thanks.

Use puma or passenger in production

Hello, I believe I can use anycable in production with 15k connections. Can I start anycable with rack? So, I might use passenger or puma.

unsubscribe callback на каналах не вызывается на обрывах соединений

Это в эни выглядит unsubscribe_from_all для subscription

  def unsubscribe_from_all(_channel)
      @stop_all_streams = true
    end

в рельсах:

   def unsubscribe_from_all
        subscriptions.each { |id, channel| remove_subscription(channel) }
      end

 def remove_subscription(subscription)
        subscription.unsubscribe_from_channel
        subscriptions.delete(subscription.identifier)
      end

  def unsubscribe_from_channel # :nodoc:
        run_callbacks :unsubscribe do
          unsubscribed
        end
      end

Anycable handle subscription

Hi! Im trying to integrate anycable in our production app and all things before broadcast was successful, but after that frontend can't receive message.

I was traced all broadcast path and realize that when client subscribe to channel not subscribed nor follow method was called, so stream_for not initialized.
After some time of researching i figure out that when AnyCable create subscription it call handle_subscribe method on channel class and after i added this method everything works as expected, but i can not found any mention of handle_subscribe method on documentation and because of this i was waste some time :)

Do i something wrong or if not - may be needed to add handle_subscribe method mention on documentation?

Env

Ruby version: 2.6.2
Rails version: 5.2.3
anycable-rails gem version: 0.6.3
anycable gem version: 0.6.0
grpc gem version: 1.17

Issues with ruby 2.6.0

Ruby version:
2.6.0

Rails version:
5.2.2

anycable gem version:
0.6.1

anycable-rails gem version:
0.6.2

grpc gem version:
1.18.0

What did you do?

created a new rails app with 2.6.0 and added gem 'anycable-rails' to my Gemfile

What did you expect to happen?

bundle exec anycable should boot anycable

What actually happened?

➜  testapp git:(master) ✗ bundle exec anycable
bundler: failed to load command: anycable (/Users/nomis/.rbenv/versions/2.6.0/bin/anycable)
LoadError: cannot load such file -- google/protobuf_c
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/google-protobuf-3.6.1-universal-darwin/lib/google/protobuf.rb:50:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/google-protobuf-3.6.1-universal-darwin/lib/google/protobuf.rb:50:in `rescue in <top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/google-protobuf-3.6.1-universal-darwin/lib/google/protobuf.rb:47:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/v1/health_pb.rb:4:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/v1/health_pb.rb:4:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/v1/health_services_pb.rb:23:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/v1/health_services_pb.rb:23:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/checker.rb:16:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/grpc-1.18.0-universal-darwin/src/ruby/pb/grpc/health/checker.rb:16:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable/server.rb:4:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable/server.rb:4:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable.rb:11:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable.rb:11:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable/cli.rb:5:in `require'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/lib/anycable/cli.rb:5:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/bin/anycable:3:in `require_relative'
  /Users/nomis/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/anycable-0.6.1/bin/anycable:3:in `<top (required)>'
  /Users/nomis/.rbenv/versions/2.6.0/bin/anycable:23:in `load'
  /Users/nomis/.rbenv/versions/2.6.0/bin/anycable:23:in `<top (required)>'

Docker with ruby alpine image throws error

I am getting the following when running bundle exec anycable. I guess that some library is missing in ruby alpine?

Edit: it does not only happen with alpine, I tried slim image too, same error

-- Control frame information -----------------------------------------------
c:0027 p:---- s:0158 e:000157 CFUNC  :add_http2_port
c:0026 p:0029 s:0152 e:000151 METHOD /usr/local/lib/ruby/2.6.0/forwardable.rb:230
c:0025 p:0012 s:0145 e:000144 BLOCK  /usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:121 [FINISH]
c:0024 p:---- s:0141 e:000140 CFUNC  :tap
c:0023 p:0018 s:0137 e:000136 METHOD /usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:120
c:0022 p:0047 s:0132 e:000131 METHOD /usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:73 [FINISH]
c:0021 p:---- s:0124 e:000123 CFUNC  :new
c:0020 p:0196 s:0119 e:000118 METHOD /usr/local/bundle/gems/anycable-0.6.1/lib/anycable/cli.rb:51
c:0019 p:0033 s:0112 e:000111 TOP    /usr/local/bundle/gems/anycable-0.6.1/bin/anycable:7 [FINISH]
c:0018 p:---- s:0107 e:000106 CFUNC  :load
c:0017 p:0109 s:0102 e:000101 TOP    /usr/local/bundle/bin/anycable:23 [FINISH]
c:0016 p:---- s:0097 e:000096 CFUNC  :load
c:0015 p:0129 s:0092 e:000091 METHOD /usr/local/lib/ruby/2.6.0/bundler/cli/exec.rb:74
c:0014 p:0075 s:0083 e:000082 METHOD /usr/local/lib/ruby/2.6.0/bundler/cli/exec.rb:28
c:0013 p:0026 s:0078 e:000077 METHOD /usr/local/lib/ruby/2.6.0/bundler/cli.rb:463
c:0012 p:0064 s:0073 e:000072 METHOD /usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/command.rb:27
c:0011 p:0047 s:0065 e:000064 METHOD /usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/invocation.rb:126
c:0010 p:0261 s:0058 e:000057 METHOD /usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor.rb:387
c:0009 p:0009 s:0045 e:000044 METHOD /usr/local/lib/ruby/2.6.0/bundler/cli.rb:27
c:0008 p:0064 s:0040 e:000039 METHOD /usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/base.rb:466
c:0007 p:0009 s:0033 e:000032 METHOD /usr/local/lib/ruby/2.6.0/bundler/cli.rb:18
c:0006 p:0076 s:0027 e:000026 BLOCK  /usr/local/lib/ruby/gems/2.6.0/gems/bundler-1.17.2/exe/bundle:30
c:0005 p:0002 s:0021 e:000020 METHOD /usr/local/lib/ruby/2.6.0/bundler/friendly_errors.rb:124
c:0004 p:0048 s:0016 E:000750 TOP    /usr/local/lib/ruby/gems/2.6.0/gems/bundler-1.17.2/exe/bundle:22 [FINISH]
c:0003 p:---- s:0013 e:000012 CFUNC  :load
c:0002 p:0109 s:0008 E:000ad0 EVAL   /usr/local/bin/bundle:23 [FINISH]
c:0001 p:0000 s:0003 E:000e70 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/usr/local/bin/bundle:23:in `<main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-1.17.2/exe/bundle:22:in `<top (required)>'
/usr/local/lib/ruby/2.6.0/bundler/friendly_errors.rb:124:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-1.17.2/exe/bundle:30:in `block in <top (required)>'
/usr/local/lib/ruby/2.6.0/bundler/cli.rb:18:in `start'
/usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/2.6.0/bundler/cli.rb:27:in `dispatch'
/usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/2.6.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/2.6.0/bundler/cli.rb:463:in `exec'
/usr/local/lib/ruby/2.6.0/bundler/cli/exec.rb:28:in `run'
/usr/local/lib/ruby/2.6.0/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/2.6.0/bundler/cli/exec.rb:74:in `load'
/usr/local/bundle/bin/anycable:23:in `<top (required)>'
/usr/local/bundle/bin/anycable:23:in `load'
/usr/local/bundle/gems/anycable-0.6.1/bin/anycable:7:in `<top (required)>'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/cli.rb:51:in `run'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/cli.rb:51:in `new'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:73:in `initialize'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:120:in `build_server'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:120:in `tap'
/usr/local/bundle/gems/anycable-0.6.1/lib/anycable/server.rb:121:in `block in build_server'
/usr/local/lib/ruby/2.6.0/forwardable.rb:230:in `add_http2_port'
/usr/local/lib/ruby/2.6.0/forwardable.rb:230:in `add_http2_port'

Authenticate response: error_msg:"undefined method `protocol' for nil:NilClass"

Tell us about your environment

Ruby version: 2.6.2

**Rails version:**5.2.2

anycable gem version: 0.6.3

**anycable-rails gem version:**0.6.4

grpc gem version: 1.17

What did you do?

I did setup anycable with existing Rails app which was using action cable earlier, I managed to have it working on dev environment but when deployed to production I get authentication error,
this issue is not related to troubleshooting but seems different.

we have deployed on heroku with two apps setup as suggested. one app is running rails application on a subdomain and another one is running anycable rpc server on another subdomain. we have supplied domain: :all option in session_store.rb.

What did you expect to happen?

Expected Anycable to work fine.

What actually happened?

Error backtrace from production.

2019-08-27T03:43:46.812300+00:00 app[web.1]: [AnyCable sid=caSj90W6eSG3l9kagpJDVD] method={} path={} format={} params={} controller=ApplicationCable::Connection action=connect status=500 error='NoMethodError: undefined method `protocol' for nil:NilClass' duration=1.33
2019-08-27T03:43:46.812368+00:00 app[web.1]: [AnyCable sid=caSj90W6eSG3l9kagpJDVD] undefined method `protocol' for nil:NilClass
2019-08-27T03:43:46.812714+00:00 app[web.1]: D 2019-08-27T03:43:46.812Z context=rpc Authenticate response: error_msg:"undefined method `protocol' for nil:NilClass"
2019-08-27T03:43:46.812907+00:00 app[web.1]: D 2019-08-27T03:43:46.812Z context=ws Websocket session initialization failed: Application error: undefined method `protocol' for nil:NilClass

Incompatible with action-cable-testing

Hi,

Anycable redefines default #delegate_connection_identifiers, where it uses connection's #fetch_identifier, which is missing in ConnectionStub.

This results in an error when trying to access identifier though test.

NoMethodError: undefined method `fetch_identifier'

The probable solution would be to use respond_to?(:fetch_identifier). What do you think?

Not able to use Anycable with Capistrano deployment

Hi @palkan thanks for your great work for anycable. 👍

I have implemented it in a rails project for my client. I was able to run anycable on my local machine in development mode as well in production mode.

But when I tried to run it on server with same configuration/settings, it didn't work. I am seeing following error message in browser's console:

WebSocket connection to 'ws://localhost:8080/cable' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

I am using Capistrano for deployment.

I am running WS server with following anycable-go command:

anycable-go -rpc=0.0.0.0:50051 -headers=cookie,x-api-token -redis=redis://localhost:6379/5 -redis_channel=anycable -addr=0.0.0.0:8080 -log

and for rpc: RAILS_ENV=production ./bin/anycable

Is there any specific setting I need to do for capistrano?

I'd be grateful for any help or suggestion on this.

Thanks

How to get connected channels to redis?

Hello again! @palkan

Last question of migration from ActionCable to AnyCable.

I have this code:

ActionCable.server.pubsub.redis_connection_for_subscriptions.pubsub('channels', "SomeChannel_#{type}_#{id}_*").each do |channel|
  ActionCable.server.broadcast(channel, data)
end

And now I have exception:

NoMethodError: undefined method `redis_connection_for_subscriptions' for #<Anycable::PubSub:0x00563a0ab8e288>

I used that code to detect connected clients and send notifications only to them.

I've tried to use ActionCable.server.pubsub.redis_conn.pubsub('channels', '...'). But only thing I can return is ['anycable']

What code should I use now?

Thanks!

Error when connecting to the channel.

Hello! I discovered strange error when I tried to integrate Anycable.
Ruby version: 2.4.0
Rails version: 5.1.0
anycable gem version: 0.6.0
anycable-rails gem version: 0.6.2
grpc gem version: 1.18.0

What did you do?

I followed common instructions on the documentation page.

What actually happened?

I catch an error - undefined method `call' for ApplicationCable::Connection:Class
You can check this gist for mode details.
This error appears when the app tries to subscribe to channel.

Load balancer setup

Hi,

We are working the following setup:

ServerA - 1 of these

  • Runs anycable-go
  • Runs redis

ServerB - 2 of these

  • Rails a rails app
  • Runs the anycable grpc gem

When websocket connections come into ServerA the anycable-go server will communication with the anycable gem over grpc and I'm planning on putting a load balancer (AWS) between the websocket and grpc servers.

Is this ok to do? Is there just 1 connection made with the grpc server or are there multiple connections? I don't really know much about grpc, I'm guessing the connections are long lived?

Thanks

Questions on how to use

This looks really great I just have some questions on how to use it.

I notice that in the installation the gem anycable-rails has group: :production next to it. Is this only able to be used in a production environment and not a development environtment? Or am I misinterpreting what production means there.

Also, when we run ./bin/anycable is that all we need to run in the terminal? When I run that command in the terminal I don't get any response. I added a print statement saying Server is running to the bin file and it does print so I am assuming the anycable server is running at that point? If the server is running then I can't use that same terminal window to run my actual api server though right? So do I need to run my rails api from a different terminal window? (the one that runs on localhost:3000 during development)

I can tell this gem is very useful I am not the best at rails yet so I will have a few questions while learning to implement this. I already implemented action cable with my rails app I just want to switch over to something faster and this seems to be able to do just that. Im sure I will have questions on deployment with this too once I get there as I am deploying using Amazon Web Services.

Thank you for building this

identified_by ломается из-за неочевидности очередности загрузки файлов/гемов

не знаю у кого как, но у меня ломается identified_by, используется не переопределенный в anycable_rails:

def identified_by(*identifiers)
      super
      Array(identifiers).each do |identifier|
        define_method(identifier) do
          instance_variable_get(:"@#{identifier}") || fetch_identifier(identifier)
        end
      end
 end

а оригинальный, через attr_accessor

На коннекте нормально все, потому что они совпадают и оба используют переменные инстанса, но вот на дисконнекте облом.

Подлечил временно тем, что поставил в коннекшен классе перед определением require

require "anycable/rails/actioncable/connection"

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :user_id

bundler: command not found: anycable

Tell us about your environment

Ruby version: 2.5.3

Rails version: 5.1.6

anycable gem version: 0.5.2

anycable-rails gem version: 0.5.5

grpc gem version: 1.6

What did you do?

bundle exec anycable

What did you expect to happen?

anycable RPC to run

What actually happened?

bundler: command not found: anycable
Install missing gem executables with `bundle install`

undefined method `camelize' for :any_cable:Symbol

Hello,

I have the following problem, every time I go to do a brodcast I get the following message:
"undefined method `camelize' for :any_cable:Symbol"

Captura de Pantalla 2019-10-16 a la(s) 6 11 23 p  m

I tried in console and in the app and in both cases I have the same problem, any suggestions?
Thank you!!

Ruby version:
2.4.4
Rails version:
5.2.1
anycable gem version:
0.6.3
anycable-rails gem version:
0.6.4
grpc gem version:
gRPC version: 1.24.0

How to run daemon mode in production?

I use capistrano deploy my rails application, but I don't figure out how to run anycable process on production use daemon mode and record logs?

# I just using stupid way 
RAILS_ENV=production bundle exec anycable --server-command "anycable-go --port 3334" &`

Add allowed request verification

Right now AnyCable missing allowed request verification, it's not a problem since many
sites lived behind some reverse proxy like an nginx, and they may configure it properly to prevent asocket hijacking.

But it's a good idea to enable such verification based on ActionCable settings, at least make a reminder for manual implementation of it since its quite simple.

ArgumentError (wrong number of arguments (given 2, expected 1))

Hello,

Please let me know the solution, So I will update the code as well
I have follow this links
https://github.com/anycable/anycable-rails

ArgumentError (wrong number of arguments (given 2, expected 1)):

anycable-rails (0.5.0) lib/anycable/rails/actioncable/connection.rb:29:in initialize' actioncable (5.0.6) lib/action_cable/server/base.rb:28:in new'
actioncable (5.0.6) lib/action_cable/server/base.rb:28:in call' actionpack (5.0.6) lib/action_dispatch/routing/mapper.rb:17:in block in class:Constraints'
actionpack (5.0.6) lib/action_dispatch/routing/mapper.rb:46:in serve' actionpack (5.0.6) lib/action_dispatch/journey/router.rb:39:in block in serve'
actionpack (5.0.6) lib/action_dispatch/journey/router.rb:26:in each' actionpack (5.0.6) lib/action_dispatch/journey/router.rb:26:in serve'
actionpack (5.0.6) lib/action_dispatch/routing/route_set.rb:727:in call' warden (1.2.7) lib/warden/manager.rb:36:in block in call'
warden (1.2.7) lib/warden/manager.rb:35:in catch' warden (1.2.7) lib/warden/manager.rb:35:in call'
rack (2.0.3) lib/rack/etag.rb:25:in call' rack (2.0.3) lib/rack/conditional_get.rb:25:in call'
rack (2.0.3) lib/rack/head.rb:12:in call' rack (2.0.3) lib/rack/session/abstract/id.rb:232:in context'
rack (2.0.3) lib/rack/session/abstract/id.rb:226:in call' actionpack (5.0.6) lib/action_dispatch/middleware/cookies.rb:613:in call'
activerecord (5.0.6) lib/active_record/migration.rb:553:in call' actionpack (5.0.6) lib/action_dispatch/middleware/callbacks.rb:38:in block in call'
activesupport (5.0.6) lib/active_support/callbacks.rb:97:in __run_callbacks__' activesupport (5.0.6) lib/active_support/callbacks.rb:750:in _run_call_callbacks'
activesupport (5.0.6) lib/active_support/callbacks.rb:90:in run_callbacks' actionpack (5.0.6) lib/action_dispatch/middleware/callbacks.rb:36:in call'
actionpack (5.0.6) lib/action_dispatch/middleware/executor.rb:12:in call' actionpack (5.0.6) lib/action_dispatch/middleware/remote_ip.rb:79:in call'
actionpack (5.0.6) lib/action_dispatch/middleware/debug_exceptions.rb:49:in call' web-console (3.5.1) lib/web_console/middleware.rb:135:in call_app'
web-console (3.5.1) lib/web_console/middleware.rb:28:in block in call' web-console (3.5.1) lib/web_console/middleware.rb:18:in catch'
web-console (3.5.1) lib/web_console/middleware.rb:18:in call' actionpack (5.0.6) lib/action_dispatch/middleware/show_exceptions.rb:31:in call'
railties (5.0.6) lib/rails/rack/logger.rb:36:in call_app' railties (5.0.6) lib/rails/rack/logger.rb:24:in block in call'
activesupport (5.0.6) lib/active_support/tagged_logging.rb:69:in block in tagged' activesupport (5.0.6) lib/active_support/tagged_logging.rb:26:in tagged'
activesupport (5.0.6) lib/active_support/tagged_logging.rb:69:in tagged' railties (5.0.6) lib/rails/rack/logger.rb:24:in call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in call' actionpack (5.0.6) lib/action_dispatch/middleware/request_id.rb:24:in call'
rack (2.0.3) lib/rack/method_override.rb:22:in call' rack (2.0.3) lib/rack/runtime.rb:22:in call'
activesupport (5.0.6) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in call' actionpack (5.0.6) lib/action_dispatch/middleware/executor.rb:12:in call'
actionpack (5.0.6) lib/action_dispatch/middleware/static.rb:136:in call' rack (2.0.3) lib/rack/sendfile.rb:111:in call'
railties (5.0.6) lib/rails/engine.rb:522:in call' puma (3.11.0) lib/puma/configuration.rb:225:in call'
puma (3.11.0) lib/puma/server.rb:624:in handle_request' puma (3.11.0) lib/puma/server.rb:438:in process_client'
puma (3.11.0) lib/puma/server.rb:302:in block in run' puma (3.11.0) lib/puma/thread_pool.rb:120:in block in spawn_thread'
Rendering /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (3.1ms)
Rendering /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.3ms)
Rendering /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.3ms)
Rendered /home/yuva/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (23.3ms)

RPC error No thread left in pool

Hi @palkan,

We chatted together on this rails issue rails/rails#33802

I had problems troubleshooting my ActionCable connexions.
I made the switch to anycable and I have to say, the transition was pretty seemless, good job on that.

I could troubleshoot a bit more as I put it in production today. It turns out that I was right : it seems to be a concurrency problem. I now have some better logs to exploit, and I have some questions:

On the gRPC service, I can find some of these logs:

RPC error, no threads available

On my rails production logs, I can find some of these:

error no treads left in pool

Here are the questions I'm asking myself:
How many threads are allocated to anycable ? Is there a way to change this ? Does it follow my puma workers / threads count ?
How does a thread handles websocket connections ? 1 thread / 1 websocket ?

I tried several methods for debugging, i made a systemd service out of anycable and ran 16 subservices in parallel. Turned out I think this might have worked because I could see some erreors about my pg max_connections topping out, but still had that thread pool limited.

I checked the ulimit of the user I run anycable with and it's fine (120 000) is there something you could help me with ?

ActionController::RoutingError (No route matches [GET] "/cable")

Hi, I wanted to use anycable for a fresh project and I encounter problem with routes.

When rails is running with anycable and anycable-go,
I got the following error

Started GET "/cable" for 127.0.0.1 at 2018-04-12 23:10:29 +0800
Started GET "/cable" for 127.0.0.1 at 2018-04-12 23:10:29 +0800
  
  
ActionController::RoutingError (No route matches [GET] "/cable"):
ActionController::RoutingError (No route matches [GET] "/cable"):
  
  
actionpack (5.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.0) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.0) lib/rails/rack/logger.rb:26:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.4) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.4) lib/rack/sendfile.rb:111:in `call'
railties (5.2.0) lib/rails/engine.rb:524:in `call'
puma (3.11.3) lib/puma/configuration.rb:225:in `call'
puma (3.11.3) lib/puma/server.rb:624:in `handle_request'
puma (3.11.3) lib/puma/server.rb:438:in `process_client'
puma (3.11.3) lib/puma/server.rb:302:in `block in run'
puma (3.11.3) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
actionpack (5.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.0) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.0) lib/rails/rack/logger.rb:26:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.4) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.0) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.4) lib/rack/sendfile.rb:111:in `call'
railties (5.2.0) lib/rails/engine.rb:524:in `call'
puma (3.11.3) lib/puma/configuration.rb:225:in `call'
puma (3.11.3) lib/puma/server.rb:624:in `handle_request'
puma (3.11.3) lib/puma/server.rb:438:in `process_client'
puma (3.11.3) lib/puma/server.rb:302:in `block in run'
puma (3.11.3) lib/puma/thread_pool.rb:120:in `block in spawn_thread'

Here are the config/application.rb

    config.action_cable.url = ENV['CABLE_URL']
    config.action_cable.mount_path = ENV['CABLE_URL'] ? nil : "/cable"

What should I do to fix this?
I am using rails 5.2, ruby 2.4.3, anycable-go 0.5.4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.