mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-08 15:50:08 +09:00
3212a683ee
Since the unread rooms stream was scoped per user, posting a message publishes the room id once to each member of the room. Each publish is a round trip to Redis, made one after another inside the request, so the time to post a message grows with the size of the room and in a big room is far more than the rest of the request. The fanout now runs in Message::BroadcastUnreadRoomJob, so the poster no longer waits for it. Who gets the notice and what it says are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuTtwJKhb77Dv7EQqv2C3C
28 lines
941 B
Ruby
28 lines
941 B
Ruby
module Message::Broadcasts
|
|
def broadcast_create
|
|
broadcast_append_to room, :messages, target: [ room, :messages ]
|
|
broadcast_unread_room_later
|
|
end
|
|
|
|
def broadcast_remove
|
|
broadcast_remove_to room, :messages
|
|
end
|
|
|
|
# Fanned out to the room's members rather than published on one global stream, so
|
|
# that the timing of activity in a room only reaches people who are in it.
|
|
def broadcast_unread_room
|
|
payload = ActiveSupport::JSON.encode(roomId: room.id)
|
|
|
|
room.memberships.pluck(:user_id).each do |user_id|
|
|
ActionCable.server.broadcast UnreadRoomsChannel.stream_name_for(user_id), payload, coder: nil
|
|
end
|
|
end
|
|
|
|
private
|
|
# The fanout is one publish per member, which in a big room takes far longer than the
|
|
# rest of posting a message, so it runs in a job rather than while the poster waits.
|
|
def broadcast_unread_room_later
|
|
Message::BroadcastUnreadRoomJob.perform_later(self)
|
|
end
|
|
end
|