diff options
Diffstat (limited to 'actioncable/lib/action_cable/channel/periodic_timers.rb')
-rw-r--r-- | actioncable/lib/action_cable/channel/periodic_timers.rb | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/actioncable/lib/action_cable/channel/periodic_timers.rb b/actioncable/lib/action_cable/channel/periodic_timers.rb new file mode 100644 index 0000000000..25fe8e5e54 --- /dev/null +++ b/actioncable/lib/action_cable/channel/periodic_timers.rb @@ -0,0 +1,41 @@ +module ActionCable + module Channel + module PeriodicTimers + extend ActiveSupport::Concern + + included do + class_attribute :periodic_timers, instance_reader: false + self.periodic_timers = [] + + after_subscribe :start_periodic_timers + after_unsubscribe :stop_periodic_timers + end + + module ClassMethods + # Allow you to call a private method <tt>every</tt> so often seconds. This periodic timer can be useful + # for sending a steady flow of updates to a client based off an object that was configured on subscription. + # It's an alternative to using streams if the channel is able to do the work internally. + def periodically(callback, every:) + self.periodic_timers += [ [ callback, every: every ] ] + end + end + + private + def active_periodic_timers + @active_periodic_timers ||= [] + end + + def start_periodic_timers + self.class.periodic_timers.each do |callback, options| + active_periodic_timers << EventMachine::PeriodicTimer.new(options[:every]) do + connection.worker_pool.async.run_periodic_timer(self, callback) + end + end + end + + def stop_periodic_timers + active_periodic_timers.each { |timer| timer.cancel } + end + end + end +end |