class ZuoraConnect::AppInstanceBase

def new_session(session: self.data_lookup, username: self.access_token, password: self.refresh_token, holding_pattern: false)

def new_session(session: self.data_lookup, username: self.access_token, password: self.refresh_token, holding_pattern: false)
  @api_version = "v2"
  @username = username
  @password = password
  @last_refresh = session["#{self.id}::last_refresh"]
  ## DEV MODE TASK DATA MOCKUP
  if ZuoraConnect.configuration.mode != "Production"
    mock_task_data = {
      "mode" => ZuoraConnect.configuration.dev_mode_mode
    }
    case ZuoraConnect.configuration.dev_mode_options.class
    when Hash
      @options = ZuoraConnect.configuration.dev_mode_options
    when Array
      mock_task_data["options"] = ZuoraConnect.configuration.dev_mode_options
    end
    ZuoraConnect.configuration.dev_mode_logins.each do |k,v|
      v = v.merge({"entities": [] }) if !v.keys.include?("entities")
      mock_task_data[k] = v
    end
    build_task(mock_task_data, session)
  else
    time_expire = (session["#{self.id}::last_refresh"] || Time.now).to_i - INSTANCE_REFRESH_WINDOW.ago.to_i
    if session.empty?
      Rails.logger.info("[#{self.id}] REFRESHING - Session Empty")
      raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
      self.refresh(session)
    elsif (self.id != session["appInstance"].to_i)
      Rails.logger.info("[#{self.id}] REFRESHING - AppInstance ID(#{self.id}) does not match session id(#{session["appInstance"].to_i})")
      raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
      self.refresh(session)
    elsif session["#{self.id}::task_data"].blank?
      Rails.logger.info("[#{self.id}] REFRESHING - Task Data Blank")
      raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
      self.refresh(session)
    elsif session["#{self.id}::last_refresh"].blank?
      Rails.logger.info("[#{self.id}] REFRESHING - No Time on Cookie")
      raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
      self.refresh(session)
    # If the cache is expired and we can aquire a refresh lock
    elsif (session["#{self.id}::last_refresh"].to_i < INSTANCE_REFRESH_WINDOW.ago.to_i) && self.mark_for_refresh
      Rails.logger.info("[#{self.id}] REFRESHING - Session Old by #{time_expire.abs} second")
      self.refresh(session)
    else
      if time_expire < 0
        Rails.logger.info(["[#{self.id}] REBUILDING - Expired by #{time_expire} seconds", self.marked_for_refresh? ? " cache updating as of #{self.reset_mark_refreshed_at} seconds ago" : nil].compact.join(','))
      else
        Rails.logger.info("[#{self.id}] REBUILDING - Expires in #{time_expire} seconds")
      end
      build_task(session["#{self.id}::task_data"], session)
    end
  end
  begin
    I18n.locale = self.locale
  rescue I18n::InvalidLocale => ex
    Rails.logger.debug("Invalid Locale: #{ex.message}")
  end
  Time.zone = self.timezone
  return self
rescue ZuoraConnect::Exceptions::HoldingPattern => ex
  while self.marked_for_refresh?
    Rails.logger.info("[#{self.id}] Holding - Expires in #{self.reset_mark_expires_at}")
    sleep(5)
  end
  self.reload_attributes([:refresh_token, :oauth_expires_at, :access_token])
  session = self.data_lookup(session: session)
  retry
end