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

Detach actioncable from the WebsocketServer and run it with the UI #18296

Merged
merged 1 commit into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ class Application < Rails::Application

# Disable ActionCable's request forgery protection
# This is basically matching a set of allowed origins which is not good for us
# Our own origin-host forgery protection is implemented in lib/websocket_server.rb
Rails.application.config.action_cable.disable_request_forgery_protection = true
config.action_cable.disable_request_forgery_protection = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

# Matching the origin against the HOST header is much more convenient
config.action_cable.allow_same_origin_as_host = true
config.action_cable.mount_path = '/ws/notifications'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify:

This says that we have action cable mounting at /ws/notifications.
This will create the route necessary to handle this.
Now action cable works like it does for other rails apps. (It just happens to use a slightly different route)


# Customize any additional options below...

Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
if Rails.env.development? && defined?(Rails::Server)
logger = Logger.new(STDOUT)
logger.level = Logger.const_get(::Settings.log.level_websocket.upcase)
mount WebsocketServer.new(:logger => logger) => '/ws'
mount WebsocketServer.new(:logger => logger) => '/ws/console'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please verify:

We didn't mount ActionCable at /ws before.
We only called it manually in WebsocketServer?

future: we are mounting websocket server at /ws/console and rails is auto mounting action cable at /ws/notifications

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

end
end
3 changes: 0 additions & 3 deletions lib/websocket_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ def initialize(options = {})
end

def call(env)
# Pass the request to ActionCable if it is for notifications
return ActionCable.server.call(env) if env['REQUEST_URI'].start_with?('/ws/notifications') && ::Settings.server.asynchronous_notifications
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verfiy:

This code no longer has notification (action cable) traffic going through here. so we no longer need to handle this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumb question, are we still using ::Settings.server.asynchronous_notifications? At this point, is it even possible to disable async notifications?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because that prevents the frontend to connect...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove that option and assume it's on? It doesn't have to be here but it seems wasteful to check if you can't operate the UI without async notifications.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you can ... if you turn it off, it would not complain, but you won't get realtime notifications.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrafanie with other words, if notifications aren't available, the frontend will keep trying to connect every minute and throw ugly errors to the user. However, if asynchronous_notifications is set to false, the frontend will not try to connect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, if it makes sense, maybe we drop the ::Settings.server.asynchronous_notifications completely in a followup PR. I don't see how there's a way to deprecate it. There is no alternative.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm still using that feature, it is really good for debugging if someone thinks that websockets break stuff in their code. It saved me multiple times :trollface:


exp = %r{^/ws/console/([a-zA-Z0-9]+)/?$}.match(env['REQUEST_URI'])
if WebSocket::Driver.websocket?(env) && same_origin_as_host?(env) && exp.present?
@logger.info("Remote console connection initiated with secret #{exp[1]}")
Expand Down
9 changes: 0 additions & 9 deletions spec/lib/websocket_server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@
let(:env) { {'REQUEST_URI' => "/ws/#{url}", 'rack.hijack' => hijack} }

describe '#call' do
context 'notifications' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

let(:url) { 'notifications' }

it 'calls actioncable' do
expect(ActionCable.server).to receive(:call).with(env)
subject.call(env)
end
end

context 'remote console' do
let(:url) { 'console/12345' }

Expand Down