Ravn::BDE::Bolt::

DeliveryNotifications module

Automated delivery notification Bolt component. Equivalent of email “DSN” - Delivery Status Notification.

Emits: - direct.bolt.received.$bolt_id

Consumes: - direct.bolt.received.$bolt_id

Public Class Methods

apply( bolt_class, from: :default )

Add some dsn-specific configuration to bolts that have DSNs.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 26
def self::apply( bolt_class, from: :default )
        super

        bolt_class.stateful_variable :expected_dsns, default: {}

        self.log.debug "Applying DSN stuff from %p to %p" % [ self, bolt_class ]
        from_segment = bolt_class.segment_for_config( from )
        bolt_class.singleton_attr_accessor( :dsns_from )
        bolt_class.dsns_from = from_segment
end

Public Instance Methods

all_dsns_received?()

Returns true if all expected DSNs have been received.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 104
def all_dsns_received?
        times = self.expected_dsns&.values or return false
        return times.all?
end
event_payload_for( phase, originating_event )

Return the ‘data’ section for the bolt message emitted during the given phase.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 80
def event_payload_for( phase, originating_event )
        payload = super

        case phase
        when :send
                payload[ :expected_dsns ] = self.expected_dsns
        when :summarize
                if originating_event.type.start_with?( 'direct.bolt.received' )
                        callsign = originating_event.callsign
                        payload[ :expected_dsns ] = { callsign => self.expected_dsns[ callsign ] }
                end
        end

        return payload
end
ready_to_be_finished?()

Returns true if the bolt should be terminated and saved to history.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 98
def ready_to_be_finished?
        return super && self.all_dsns_received?
end
receive_phase( event )

Overloaded to send the automated dsn.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 48
def receive_phase( event )
        super

        data = {
                instance_id: event.data[:instance_id]
        }
        fields = { to: event.callsign, data: data }

        return self.send_message( 'direct.bolt.received.${bolt_id}', fields )
end
recipient_segment_members()

Fetch the map of who DSNs are expected from at the current moment as a Hash keyed by callsign.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 112
def recipient_segment_members
        segment_members = self.class.dsns_from.to_h
        segment_members.delete( Ravn::BDE.callsign )
        return segment_members
end
send_phase( event )

Overloaded to set up the expected dsn table.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 39
def send_phase( event )
        self.expected_dsns = self.recipient_segment_members
        self.log.debug "Expecting DSN from %d recipients" % [ self.expected_dsns.size ]

        super
end
summarize_phase( event )

Overloaded to record dsn. This may finish the bolt (via super) if it was the last expected dsn.

# File lib/ravn/bde/bolt/delivery_notifications.rb, line 62
def summarize_phase( event )
        if self.is_target_of?( event )
                if event.type.start_with?( 'direct.bolt.received' )
                        callsign = event.callsign or raise "event is missing a callsign"
                        self.log.info "Got DSN for %s [%s] from %s" %
                                [ self.class.name, self.id, callsign ]
                        self.expected_dsns = self.expected_dsns.merge( callsign => Ravn.time )
                end
        else
                self.log.warn "Ignoring event from another instance! %p" % [ event ]
        end

        super
end