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:
parent
5c39e4b1c0
commit
45435cbbd5
|
@ -12,12 +12,23 @@ export default {
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
this.messageBus = container.lookup("service:message-bus");
|
this.messageBus = container.lookup("service:message-bus");
|
||||||
this.dialog = container.lookup("service:dialog");
|
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() {
|
teardown() {
|
||||||
this.messageBus.unsubscribe("/logout", this.onMessage);
|
if (this.currentUser) {
|
||||||
|
this.messageBus.unsubscribe(
|
||||||
|
`/logout/${this.currentUser.id}`,
|
||||||
|
this.onMessage
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
|
|
|
@ -335,7 +335,7 @@ acceptance("User - Logout", function (needs) {
|
||||||
test("Dialog works", async function (assert) {
|
test("Dialog works", async function (assert) {
|
||||||
sinon.stub(logout, "default");
|
sinon.stub(logout, "default");
|
||||||
await visit("/u/eviltrout");
|
await visit("/u/eviltrout");
|
||||||
await publishToMessageBus("/logout");
|
await publishToMessageBus("/logout/19");
|
||||||
|
|
||||||
assert.ok(exists(".dialog-body"));
|
assert.ok(exists(".dialog-body"));
|
||||||
assert.ok(
|
assert.ok(
|
||||||
|
|
|
@ -1497,7 +1497,7 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def logged_out
|
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)
|
DiscourseEvent.trigger(:user_logged_out, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ class UserDestroyer
|
||||||
StaffActionLogger.new(deleted_by).log_user_deletion(user, opts.slice(:context))
|
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?
|
Rails.logger.warn("User destroyed without context from: #{caller_locations(14, 1)[0]}") if opts.slice(:context).blank?
|
||||||
end
|
end
|
||||||
MessageBus.publish "/logout", result.id, user_ids: [result.id]
|
MessageBus.publish "/logout/#{result.id}", result.id, user_ids: [result.id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2020,7 +2020,7 @@ RSpec.describe User do
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
it 'should publish the right message' do
|
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)
|
expect(message.data).to eq(user.id)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue