lib/demux/demuxer.rb
# frozen_string_literal: true
module Demux
# Demux::Demuxer is the heart of pairing signals to apps.
# It's a base implementation of what needs to happen, but apps can
# provide their own custom demuxer that calls out to this one.
#
# For example a host application will likely want to process signals in a
# background queue and can supply their own demuxer with details on how that
# should happen.
class Demuxer
# Return the agruments that will be needed to re-initialize a custom
# demuxer. These might be used to pass to a job in which the custom demuxer
# would call resolve_now
#
# @returns [Hash] hash representing the signal_attributes for initializing
# the demuxer
attr_reader :demuxer_arguments
def initialize(**args)
@demuxer_arguments = args
@signal_attributes = SignalAttributes.new(**@demuxer_arguments)
@account_id = @signal_attributes.account_id
@account_type = @signal_attributes.account_type
@signal_class = @signal_attributes.signal_class
end
# Called by signal to resolve transmissions.
#
# If you are implementing a custom demuxer, you can override this method
# to provide your own implementation as long as you ultimately call
# `#resolve_now` in your new implementation.
#
# @return [self]
def resolve
resolve_now
self
end
# Called by the implementation of #resolve to immediately resolve
# transmissions from a signal.
#
# @return [self]
def resolve_now
queue_transmissions
queued_transmissions.each do |transmission|
transmit(transmission)
end
self
end
# Called in `#resolve_now` when a resolved transmission is ready to be
# transmitted. You can override this in a custom demuxer as long as you
# ultimately call `#transmit` on the transmission.
#
# @return [self]
def transmit(transmission)
transmission.transmit
self
end
private
def queued_transmissions
Transmission
.queued
.for_app(listening_apps)
.where(uniqueness_hash: @signal_attributes.hashed)
end
def queue_transmissions
listening_apps.transmission_requested_all(@signal_attributes)
self
end
def listening_apps
Demux::App.listening_for(
signal_name: @signal_class.constantize.signal_name,
account_id: @account_id,
account_type: @account_type
)
end
end
end