-
Notifications
You must be signed in to change notification settings - Fork 897
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
Conversation
c127ca9
to
d7d2824
Compare
Checked commit skateman@d7d2824 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. Took me a little while.
As long as you can verify my logic, then I'm 👍
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
config.action_cable.disable_request_forgery_protection = false | ||
# 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' |
There was a problem hiding this comment.
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)
@@ -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' |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
@@ -17,15 +17,6 @@ | |||
let(:env) { {'REQUEST_URI' => "/ws/#{url}", 'rack.hijack' => hijack} } | |||
|
|||
describe '#call' do | |||
context 'notifications' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
cc @jrafanie |
@skateman Does this mean the WebsocketWorker goes away? From the way it's described in ManageIQ/manageiq-appliance#219 it sounds like all the traffic is handled by the UiWorker. Is that right? (I admit I don't understand the solution's architecture here) |
@Fryguy no, |
👍 |
@skateman this looks great to me. From a high level, do we need to change anything else in regards to how we boot puma/configure apache/load balancers besides what you've already done in ManageIQ/manageiq-appliance#219. In other words, are there followup PRs you know we need to do? |
@jrafanie no, this will work well after the 2PRs are merged and I can continue with adding cockpit support to the proxy. |
@skateman Can you open a placeholder issue for yourself to rename the WebSocketWorker to RemoteConsoleWorker (as per #18296 (comment) ) |
As the remote console implementation is growing, I think it is the right time to start using the worker for the remote consoles only. I looked up the documentation of ActionCable and realized that we were already running it under the default
/cable
endpoint. The reverse proxy configuration on the appliances masked this, so it is not really exposed in production. However, it consumes up to 5 worker threads just because.So I was thinking why don't we use this embedded solution only? This way I can reduce the complexity of the
WebsocketServer
a little and maybe even rename it in the future.evm:start
.@skateman you have to test this on an applianceMerge with ManageIQ/manageiq-appliance#219
Parent issue: #18300