class Segmentor::Segment
Segment
is a slice of data, based on a condition.
Constants
- NO_REPEAT
Public Class Methods
# File lib/segmentor/segment.rb, line 22 def self.after_session_change(method_name) self._after_session_change = method_name end
Public Instance Methods
turns a session from draft into active and marks the current active session as archived. if no current active session is found. the latest session is marked as active
# File lib/segmentor/segment.rb, line 113 def activate(session) ::ActiveRecord::Base.transaction do # mark the current active session as archived as = active_session if as as.status = ::Segmentor::Session::ARCHIVED as.save! end # mark the new session as active session.status = ::Segmentor::Session::ACTIVE session.save! end end
# File lib/segmentor/segment.rb, line 128 def active_session sessions.active.first end
# File lib/segmentor/segment.rb, line 132 def active_session! as = active_session raise ::Segmentor::Errors::NoSessionError, 'no active session' unless as as end
generate all the targets for this segment it then returns the session
# File lib/segmentor/segment.rb, line 40 def generate! # start a new session session = start_session begin # get the data from the source returned_targets = source.execute # replace the data in the segment in a transaction returned_targets.each do |target| target.session = session target.save! end # mark the session as draft end_session(session) activate(session) if auto_activate session rescue ::Segmentor::Errors::EvaluationError => e # mark the session as failed with a reason. don't raise session.mark_as_failed!(e.message) session rescue StandardError # delete the session and raise session.destroy raise end end
# File lib/segmentor/segment.rb, line 105 def last_run # latest_session is going to be either active, draft or failed latest_session.try(:updated_at) end
# File lib/segmentor/segment.rb, line 139 def latest_session(include_running: false) unaccepted_status = [::Segmentor::Session::ARCHIVED] unaccepted_status << ::Segmentor::Session::IN_PROGRESS unless include_running # pick the latest session that's not in progress or archived sessions.where .not(status: unaccepted_status) .order(created_at: :desc) .first end
notify! calls the given block for each target that can be notified if the block raises a Segmentor::Errors::NotificationError
, the target is skipped and no receipt is issued but the rest of the targets are still notified as most notification systems do not support transactions, it is important to ensure only ::Segmentor::Errors::NotificationError
is raised unless you are sure you want to rollback all notification receipts
# File lib/segmentor/segment.rb, line 76 def notify!(&block) # get the active targets from the segment # for each target, check if its receipt is within segment repeat frequency # if not, send the notification and generate a receipt # if so, do nothing raise ::Segmentor::Errors::NoSessionError, 'no active session' unless active_session ::ActiveRecord::Base.transaction do active_session.targets.each do |target| next unless target.can_be_notified? # send the notification # generate a receipt result = block.call(target, notifier_context) if block_given? target.issue_receipt!(result) # catch ::Segmentor::Errors::NotificationError and do nothing rescue ::Segmentor::Errors::NotificationError # do nothing. so we only skip issue_receipt! but continue to the rest of the targets # any other error will be raised and rollback the transaction end active_session.touch end end
resets the last session of this segment to be in progress again
# File lib/segmentor/segment.rb, line 101 def reset! latest_session.mark_as_draft! end
Private Instance Methods
# File lib/segmentor/segment.rb, line 159 def end_session(session) session.mark_as_draft! end
# File lib/segmentor/segment.rb, line 152 def start_session session = ::Segmentor::Session.new(segment: self) session.save! session end