lib/resque/plugins/app_instance_job.rb



module Resque
  module Plugins
    module AppInstanceJob
      def around_perform(args)
        case args.class.to_s
        when "Array"
          if args.first.class == Hash
            data = args.first.merge({:worker_class => self.to_s})
          else
            data = {:worker_class => self.to_s, :args => args}
          end
        when "Hash"
          data = args.merge({:worker_class => self.to_s})
        end
        if Rails.logger.is_a?(Ougai::Logger) 
          Rails.logger.with_fields = {job: data, trace_id: SecureRandom.uuid, name: "RailsWorker"}
        end

        begin
          connection_count ||= 0 
          @appinstance = ZuoraConnect::AppInstance.find(args['app_instance_id'].to_i)
          Rails.logger.info('Starting job') 

          @appinstance.new_session(holding_pattern: true)
        rescue ActiveRecord::RecordNotFound => exception
          # If we can't find app_instance let make sure we cleanup
          Rails.logger.info("No instance found, purge")
          ZuoraConnect::AppInstance.new(id: args['app_instance_id'].to_i).prune_data
          return
        rescue ActiveRecord::StatementInvalid => exception
          if (connection_count += 1) <= 3 &&
            (
              exception.message.include?("PG::UnableToSend: no connection to the server") ||
              exception.message.include?("PG::ConnectionBad: PQconsumeInput()") ||
              exception.message.include?("PG::ConnectionBad: PQsocket()") ||
              exception.message.include?("PG::UnableToSend: SSL SYSCALL")
            )

            sleep 30
            ActiveRecord::Base.establish_connection
            retry
          else
            raise
          end
        rescue PG::ConnectionBad => exception
          Rails.logger.info("Bad Connection Restart")
          Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
          return
        rescue ZuoraConnect::Exceptions::ConnectCommunicationError => exception
          Rails.logger.warn("Enqueue Job Again ~ 2 mins", exception)
          @appinstance.queue_pause(time: 2.minutes.to_i) 
          Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
          return
        rescue Net::ReadTimeout, Net::OpenTimeout, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => exception
          Rails.logger.warn("Enqueue Job Again ~ 2 mins", exception)
          @appinstance.queue_pause(time: 2.minutes.to_i) 
          Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
          return
        end
        yield
      rescue
        raise
      ensure
        @appinstance.cache_app_instance if defined?(@appinstance)
        Rails.logger.flush if Rails.logger.methods.include?(:flush)
      end
    end
  end
end