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, intent) ⇒ FutureResult

[ GitHub ]

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

def initialize(pool, intent)
  @mutex = Mutex.new

  @session = nil
  @pool = pool
  @intent = intent

  @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 55

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 140

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

#lock_wait (readonly)

[ GitHub ]

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

attr_reader :lock_wait

#pending?Boolean (readonly)

[ GitHub ]

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

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

Instance Method Details

#cancel

[ GitHub ]

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

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

#empty?Boolean

[ GitHub ]

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

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

#exec_query(connection, intent, async: false) (private)

[ GitHub ]

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

def exec_query(connection, intent, async: false)
  # Update intent with actual async execution mode for accurate logging
  intent.async = async

  connection.raw_exec_query(intent)
end

#execute!(connection)

[ GitHub ]

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

def execute!(connection)
  execute_query(connection)
end

#execute_or_skip

[ GitHub ]

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

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)
          ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] = @event_buffer

          execute_query(connection, async: true)
        end
      ensure
        @mutex.unlock
      end
    end
  end
end

#execute_or_wait (private)

[ GitHub ]

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

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 162

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

#result

[ GitHub ]

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

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 86

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

#then(&block)

[ GitHub ]

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

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

#to_a

[ GitHub ]

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

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