class Segmentor::Segment

Segment is a slice of data, based on a condition.

Constants

NO_REPEAT

Public Class Methods

after_session_change(method_name) click to toggle source
# File lib/segmentor/segment.rb, line 22
def self.after_session_change(method_name)
  self._after_session_change = method_name
end

Public Instance Methods

activate(session) click to toggle source

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
active_session() click to toggle source
# File lib/segmentor/segment.rb, line 128
def active_session
  sessions.active.first
end
active_session!() click to toggle source
# 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!() click to toggle source

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
last_run() click to toggle source
# 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
latest_session(include_running: false) click to toggle source
# 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!(&block) click to toggle source

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
reset!() click to toggle source

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

end_session(session) click to toggle source
# File lib/segmentor/segment.rb, line 159
def end_session(session)
  session.mark_as_draft!
end
start_session() click to toggle source
# File lib/segmentor/segment.rb, line 152
def start_session
  session = ::Segmentor::Session.new(segment: self)
  session.save!

  session
end