Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Action Cable: allow multiple instances of Server::Base with different configs #34714

Merged

Conversation

@palkan
Copy link
Contributor

@palkan palkan commented Dec 15, 2018

Context

When trying to create a separate cable instance (e.g. within an engine), we faced a problem of ActionCable::Server::Base relying on the global configuration (i.e. ActionCable::Server::Base.config).

We want our engine to have a separate, isolated, Cable server instance with its own configuration.

See the example app using this patch: https://github.com/palkan/engine-cable-app

Summary

  • Add ability to pass a config as a Server.new argument.

Other Information

This problem has been already discussed here: #27425 (comment) (we've adjusted the test from that PR as well).

The related issue not included into this patch (separate PR?): currently, only the Redis adapter supports channels prefixes. With the ability to have engined cables we'll need to isolate streams for all distributed adapters (e.g. postgresql, async/inline adapters do not share anything).

One potential caveat of using multiples cables within the app is the lack of isolation for channel classes, i.e. it is possible to subscribe (or at least try to) to any channel from any connection (see https://github.com/rails/rails/blob/v5.2.2/actioncable/lib/action_cable/connection/subscriptions.rb#L35).

One possible solution is to add config.base_channel_class parameter and use it instead of a ActionCable::Channel::Base (i.e. config.base_channel_class >= subscription_klass).

Another way is to get away from using Ruby class names as identifiers, and build a per-connection registry/map of identifiers->class (like it's done in https://github.com/palkan/litecable).

P.S. Thanks to @composerinteralia for pairing with me on this feature.

@jeremy
Copy link
Member

@jeremy jeremy commented Dec 15, 2018

Cool, @palkan. Could you share the motivation/pressures behind running a separate cable server in the engine, vs using a single server and providing channels within the engine?

@palkan
Copy link
Contributor Author

@palkan palkan commented Dec 15, 2018

Could you share the motivation/pressures behind running a separate cable server in the engine, vs using a single server and providing channels within the engine?

Separate cable server allows you to:

  • use a different set of identifiers
  • use a different authentication strategy (we perform authentication within a Connection class and authorization within a Channel class).

My particular use-case is the following: I'm building a Admin Console engine for the app, I'd like to add real-time functionality in the future, but I don't want to worry about whether the main app has its own cable, will there be any conflicts, etc..

So, I want an isolated, plug-n-play, way to add real-time functionality to the app: just drop a gem and that's it.

@rmacklin
Copy link
Contributor

@rmacklin rmacklin commented Jan 12, 2019

So, I want an isolated, plug-n-play, way to add real-time functionality to the app: just drop a gem and that's it.

That's an interesting idea! Would be interested in hearing how it turns out.

@palkan
Copy link
Contributor Author

@palkan palkan commented Jan 15, 2019

@kaspth could you please put this one on your list too?)

@kaspth
Copy link
Member

@kaspth kaspth commented Jan 24, 2019

Looks good! We'll just need a changelog entry and then squash your commits to 1, thanks!

@palkan palkan force-pushed the chore/refactor-action-cable-server-config branch from a10f29b to 35407dd Jan 25, 2019
@palkan
Copy link
Contributor Author

@palkan palkan commented Jan 25, 2019

@kaspth Done! 🙂

That allows us to create a separate, isolated Action Cable server
instance within the same app.
@palkan palkan force-pushed the chore/refactor-action-cable-server-config branch from 35407dd to 3cd69fa Feb 12, 2019
@palkan
Copy link
Contributor Author

@palkan palkan commented Feb 12, 2019

@kaspth Just a friendly reminder) Rebased and ready to be merged

@shinespark
Copy link

@shinespark shinespark commented Feb 12, 2019

@kaspth
Copy link
Member

@kaspth kaspth commented Feb 12, 2019

Hey-oh!! I thought there was something I needed to look into with this, which is why I kept procrastinating, but nope, it's all good! 😄❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants