Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions spec/cable/server_spec.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "../spec_helper"
require "log/spec"

include RequestHelpers

Expand Down Expand Up @@ -47,6 +48,34 @@ describe Cable::Server do
end
end

describe "#send_to_channels" do
it "logs a single line per broadcast regardless of the number of subscribers" do
Cable.reset_server
Cable.temp_config(backend_class: Cable::DevBackend) do
connection_1 = creates_new_connection("aa")
connection_2 = creates_new_connection("bb")

Cable.server.add_connection(connection_1)
Cable.server.add_connection(connection_2)

# Both connections stream from the same identifier ("chat_room_a")
connection_1.subscribe(subscribe_payload("room_a"))
connection_2.subscribe(subscribe_payload("room_a"))

logs = Log.capture("cable") do
Cable.server.send_to_channels("chat_room_a", {"message" => "hi"}.to_json)
end

logs.check(:info, /Transmitting .* to 2 subscribers \(via streamed from chat_room_a\)/)
logs.empty

connection_1.close
connection_2.close
end
Cable.reset_server
end
end

describe "#subscribed_channels_for" do
it "accurately returns active channel subscriptions for a specificic token" do
Cable.reset_server
Expand Down
9 changes: 8 additions & 1 deletion src/cable/server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ module Cable
return unless @channels.has_key?(channel_identifier)

parsed_message = safe_decode_message(message)
transmitted = 0

begin
@channels[channel_identifier].each do |channel|
Expand All @@ -143,13 +144,19 @@ module Cable
if channel.connection.closed?
channel.close
else
Cable::Logger.info { "#{channel.class} transmitting #{parsed_message} (via streamed from #{channel.stream_identifier})" }
channel.connection.socket.send({
identifier: channel.identifier,
message: parsed_message,
}.to_json)
transmitted += 1
end
end

# Log once per broadcast event rather than once per subscriber, so a
# message fanned out to N connections produces a single log line.
if transmitted > 0
Cable::Logger.info { "Transmitting #{parsed_message} to #{transmitted} subscriber#{"s" if transmitted > 1} (via streamed from #{channel_identifier})" }
end
rescue e : IO::Error
Cable.settings.on_error.call(e, "IO::Error Exception: #{e.message}: #{parsed_message} -> Cable::Server#send_to_channels(channel, message)", nil)
end
Expand Down
Loading