123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::FutureResult

Do not use. This class is for internal use only.
Relationships & Source Files
Namespace Children
Classes:
Extension / Inclusion / Inheritance Descendants
Subclasses:
Inherits: Object
Defined in: activerecord/lib/active_record/future_result.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(pool, *args, **kwargs) ⇒ FutureResult

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 66

def initialize(pool, *args, **kwargs)
  @mutex = Mutex.new

  @session = nil
  @pool = pool
  @args = args
  @kwargs = kwargs

  @pending = true
  @error = nil
  @result = nil
  @instrumenter = ActiveSupport::Notifications.instrumenter
  @event_buffer = nil
end

Class Method Details

.wrap(result)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 53

def self.wrap(result)
  case result
  when self, Complete
    result
  else
    Complete.new(result)
  end
end

Instance Attribute Details

#canceled?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 139

def canceled?
  @session && !@session.active?
end

#lock_wait (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 64

attr_reader :lock_wait

#pending?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 135

def pending?
  @pending && (!@session || @session.active?)
end

Instance Method Details

#cancel

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 94

def cancel
  @pending = false
  @error = Canceled
  self
end

#empty?Boolean

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 62

delegate :empty?, :to_a, to: :result

#exec_query(connection, *args, **kwargs) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 169

def exec_query(connection, *args, **kwargs)
  connection.raw_exec_query(*args, **kwargs)
end

#execute!(connection)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 90

def execute!(connection)
  execute_query(connection)
end

#execute_or_skip

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 100

def execute_or_skip
  return unless pending?

  @session.synchronize do
    return unless pending?

    @pool.with_connection do |connection|
      return unless @mutex.try_lock
      begin
        if pending?
          @event_buffer = EventBuffer.new(self, @instrumenter)
          connection.with_instrumenter(@event_buffer) do
            execute_query(connection, async: true)
          end
        end
      ensure
        @mutex.unlock
      end
    end
  end
end

#execute_or_wait (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 144

def execute_or_wait
  if pending?
    start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
    @mutex.synchronize do
      if pending?
        @pool.with_connection do |connection|
          execute_query(connection)
        end
      else
        @lock_wait = (Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) - start)
      end
    end
  else
    @lock_wait = 0.0
  end
end

#execute_query(connection, async: false) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 161

def execute_query(connection, async: false)
  @result = exec_query(connection, *@args, **@kwargs, async: async)
rescue => error
  @error = error
ensure
  @pending = false
end

#result

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 122

def result
  execute_or_wait
  @event_buffer&.flush

  if canceled?
    raise Canceled
  elsif @error
    raise @error
  else
    @result
  end
end

#schedule!(session)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 85

def schedule!(session)
  @session = session
  @pool.schedule_query(self)
end

#then(&block)

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 81

def then(&block)
  Promise.new(self, block)
end

#to_a

[ GitHub ]

  
# File 'activerecord/lib/active_record/future_result.rb', line 62

delegate :empty?, :to_a, to: :result