PERF: Use user-specific channel for message-bus logout (#19719)

Using a shared channel means that every user receives an update to the 'last_id' when *any* other user is logged out. If many users are being programmatically logged out at the same time, this can cause a very large number of message-bus polls.

This commit switches to use a user-specific channel, which means that each user has its own 'last id' which will only increment when they are logged out
This commit is contained in:
David Taylor 2023-01-04 19:55:52 +00:00 committed by GitHub
parent 5c39e4b1c0
commit 45435cbbd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 6 deletions

View File

@ -12,12 +12,23 @@ export default {
initialize(container) {
this.messageBus = container.lookup("service:message-bus");
this.dialog = container.lookup("service:dialog");
this.currentUser = container.lookup("service:current-user");
this.messageBus.subscribe("/logout", this.onMessage);
if (this.currentUser) {
this.messageBus.subscribe(
`/logout/${this.currentUser.id}`,
this.onMessage
);
}
},
teardown() {
this.messageBus.unsubscribe("/logout", this.onMessage);
if (this.currentUser) {
this.messageBus.unsubscribe(
`/logout/${this.currentUser.id}`,
this.onMessage
);
}
},
@bind

View File

@ -335,7 +335,7 @@ acceptance("User - Logout", function (needs) {
test("Dialog works", async function (assert) {
sinon.stub(logout, "default");
await visit("/u/eviltrout");
await publishToMessageBus("/logout");
await publishToMessageBus("/logout/19");
assert.ok(exists(".dialog-body"));
assert.ok(

View File

@ -1497,7 +1497,7 @@ class User < ActiveRecord::Base
end
def logged_out
MessageBus.publish "/logout", self.id, user_ids: [self.id]
MessageBus.publish "/logout/#{self.id}", self.id, user_ids: [self.id]
DiscourseEvent.trigger(:user_logged_out, self)
end

View File

@ -103,7 +103,7 @@ class UserDestroyer
StaffActionLogger.new(deleted_by).log_user_deletion(user, opts.slice(:context))
Rails.logger.warn("User destroyed without context from: #{caller_locations(14, 1)[0]}") if opts.slice(:context).blank?
end
MessageBus.publish "/logout", result.id, user_ids: [result.id]
MessageBus.publish "/logout/#{result.id}", result.id, user_ids: [result.id]
end
end

View File

@ -2020,7 +2020,7 @@ RSpec.describe User do
fab!(:user) { Fabricate(:user) }
it 'should publish the right message' do
message = MessageBus.track_publish('/logout') { user.logged_out }.first
message = MessageBus.track_publish("/logout/#{user.id}") { user.logged_out }.first
expect(message.data).to eq(user.id)
end