DEV: Various behind-the-scenes improvements to PresenceChannel (#14518)

- Allow the `/presence/get` endpoint to return multiple channels in a single request (limited to 50)
- When multiple presence channels are initialized in a single Ember runloop, batch them into a single GET request
- Introduce the `presence-pretender` to allow easy testing of PresenceChannel-related features
- Introduce a `use_cache` boolean (default true) on the the server-side PresenceChannel initializer. Useful during testing.
This commit is contained in:
David Taylor
2021-10-07 15:50:14 +01:00
committed by GitHub
parent ba380c5f52
commit a55642a30a
7 changed files with 251 additions and 81 deletions

View File

@ -4,22 +4,35 @@ class PresenceController < ApplicationController
skip_before_action :check_xhr
before_action :ensure_logged_in, only: [:update]
MAX_CHANNELS_PER_REQUEST ||= 50
def get
name = params.require(:channel)
names = params.require(:channels)
raise Discourse::InvalidParameters.new(:channels) if !(names.is_a?(Array) && names.all? { |n| n.is_a? String })
begin
names.uniq!
raise Discourse::InvalidParameters.new("Too many channels") if names.length > MAX_CHANNELS_PER_REQUEST
user_group_ids = if current_user
GroupUser.where(user_id: current_user.id).pluck("group_id")
else
[]
end
result = {}
names.each do |name|
channel = PresenceChannel.new(name)
if channel.can_view?(user_id: current_user&.id, group_ids: user_group_ids)
result[name] = PresenceChannelStateSerializer.new(channel.state, root: nil)
else
result[name] = nil
end
rescue PresenceChannel::NotFound
raise Discourse::NotFound
result[name] = nil
end
if !channel.can_view?(user_id: current_user&.id)
# Do not reveal existence of channel
raise Discourse::NotFound
end
state = channel.state
render json: state, serializer: PresenceChannelStateSerializer, root: nil
render json: result
end
def update
@ -39,7 +52,7 @@ class PresenceController < ApplicationController
raise Discourse::InvalidParameters.new(:leave_channels)
end
if present_channels && present_channels.length > 50
if present_channels && present_channels.length > MAX_CHANNELS_PER_REQUEST
raise Discourse::InvalidParameters.new("Too many present_channels")
end