DEV: Centralize user updates to a single MessageBus channel. (#17058)

Introduces an interface to publish user updates on the server side and
helps to reduce the growing number of subscriptions on the client side.
This commit is contained in:
Alan Guo Xiang Tan
2022-06-13 14:27:43 +08:00
committed by GitHub
parent bd32656157
commit 94c3bbc2d1
9 changed files with 92 additions and 49 deletions

View File

@@ -657,16 +657,38 @@ class User < ActiveRecord::Base
MessageBus.publish("/notification/#{id}", payload, user_ids: [id])
end
PUBLISH_USER_STATUS_TYPE = "user_status"
PUBLISH_DO_NOT_STATUS_TYPE = "do_not_disturb"
PUBLISH_DRAFTS_TYPE = "drafts"
def self.publish_updates_channel(user_id)
"/user-updates/#{user_id}"
end
def self.publish_updates(user_id:, type:, payload:)
MessageBus.publish(
publish_updates_channel(user_id),
{
type: type,
payload: payload
},
user_ids: [user_id]
)
end
def publish_updates(type:, payload:)
self.class.publish_updates(user_id: id, type: type, payload: payload)
end
def publish_do_not_disturb(ends_at: nil)
MessageBus.publish("/do-not-disturb/#{id}", { ends_at: ends_at&.httpdate }, user_ids: [id])
publish_updates(type: PUBLISH_DO_NOT_STATUS_TYPE, payload: { ends_at: ends_at&.httpdate })
end
def publish_user_status(status)
payload = status ?
{ description: status.description, emoji: status.emoji } :
nil
MessageBus.publish("/user-status/#{id}", payload, user_ids: [id])
publish_updates(
type: PUBLISH_USER_STATUS_TYPE,
payload: status ? { description: status.description, emoji: status.emoji } : nil
)
end
def password=(password)

View File

@@ -214,13 +214,13 @@ class UserStat < ActiveRecord::Base
RETURNING draft_count, (SELECT 1 FROM drafts WHERE user_id = :user_id AND draft_key = :new_topic)
SQL
MessageBus.publish(
"/user-drafts/#{user_id}",
{
User.publish_updates(
user_id: user_id,
type: User::PUBLISH_DRAFTS_TYPE,
payload: {
draft_count: draft_count,
has_topic_draft: !!has_topic_draft
},
user_ids: [user_id]
}
)
else
DB.exec <<~SQL