2

In my Rails view I’m using turbo_stream_from to subscribe to a turbo stream broadcast to display a list of patients:

<%= turbo_stream_from :all_patients %>

I want this list to be updated when a new patient is created, so I call:

constly_method
Turbo::StreamsChannel.broadcast_update_to(:all_patients,...)

However, I want to run this code only if there are any clients that are actually subscribed to :all_patients at the moment, because this code takes some computing resources. So, I want something like

if Turbo::StreamsChannel.broadcast_subscribed?(:all_patients)
  constly_method
  Turbo::StreamsChannel.broadcast_update_to(:all_patients,...)
end

Is there any way to check that?

Evgenii
  • 36,389
  • 27
  • 134
  • 170

2 Answers2

0

ActionCanble data can be accessed with query. For Example

ActionCable.server.remote_connections.where(current_user: User.find(1)).disconnect

Documentation: https://api.rubyonrails.org/v7.0/classes/ActionCable/RemoteConnections.html

It good to play around with the query to solve the problem. (If you will find accurate query. Message me to comment. I will enrich my post with it). Hope this help

itsnikolay
  • 17,415
  • 4
  • 65
  • 64
0
<%= turbo_stream_from "channel_name" %> # on one page
<%= turbo_stream_from User.first %>     # on another page

Redis keeps track of some of it:

>> redis = Redis.new

# active channels
>> channels = redis.pubsub("channels") 
=> ["Z2lkOi8vc3RhY2tvdmVyZmxvdy9Vc2VyLzE", "_action_cable_internal", "channel_name"]

# subscribers, which are ActionCable servers
>> redis.pubsub("numsub", channels)
=> ["Z2lkOi8vc3RhY2tvdmVyZmxvdy9Vc2VyLzE", 1, "_action_cable_internal", 1, "channel_name", 1]

Number of actual users connected, I don't think matters:

>> redis.pubsub("numsub", channels)
=> ["Z2lkOi8vc3RhY2tvdmVyZmxvdy9Vc2VyLzE", 0, "_action_cable_internal", 1, "channel_name", 1]
#                                          ^
# if i close user page, ActionCable disconnects from that channel

>> redis.pubsub("channels") 
=> ["_action_cable_internal", "channel_name"]

https://redis.io/commands/pubsub-channels/


This one only works per server instance and gives you the number of streams connected for each channel:

ActionCable.server.connections.flat_map do |conn|
  conn.subscriptions.send(:subscriptions).values
end.flat_map do |channel|
  # also streams seem to get stuck when code reloads in development
  # count goes up with every code change. must be a bug.
  channel.send(:streams).keys
end.tally
# => {"channel_name"=>4, "Z2lkOi8vc3RhY2tvdmVyZmxvdy9Vc2VyLzE"=>1}
Alex
  • 16,409
  • 6
  • 40
  • 56