Module: PgPipeline::PoolOps

Defined in:
lib/pg_pipeline/pool.rb

Class Method Summary collapse

Class Method Details

.finite_float!(value, name, allow_zero: false) ⇒ Object



625
626
627
628
629
630
631
632
633
634
# File 'lib/pg_pipeline/pool.rb', line 625

def finite_float!(value, name, allow_zero: false)
  number = Float(value)
  bound_ok = allow_zero ? number >= 0 : number.positive?
  raise ArgumentError unless number.finite? && bound_ok

  number
rescue ArgumentError, TypeError
  requirement = allow_zero ? "non-negative finite" : "positive finite"
  raise ArgumentError, "#{name} must be a #{requirement} number (got #{value.inspect})"
end

.new_connection(connection_args) ⇒ Object



681
682
683
# File 'lib/pg_pipeline/pool.rb', line 681

def new_connection(connection_args)
  connection_args.nil? ? PG::Connection.new : PG::Connection.new(connection_args)
end

.nonnegative_integer!(value, name) ⇒ Object



636
637
638
639
640
641
642
643
# File 'lib/pg_pipeline/pool.rb', line 636

def nonnegative_integer!(value, name)
  integer = Integer(value)
  raise ArgumentError, "#{name} must be >= 0" if integer.negative?

  integer
rescue ArgumentError, TypeError
  raise ArgumentError, "#{name} must be an integer >= 0"
end

.positive_integer!(value, name) ⇒ Object



616
617
618
619
620
621
622
623
# File 'lib/pg_pipeline/pool.rb', line 616

def positive_integer!(value, name)
  integer = Integer(value)
  raise ArgumentError, "#{name} must be >= 1" if integer < 1

  integer
rescue ArgumentError, TypeError
  raise ArgumentError, "#{name} must be an integer >= 1"
end

.safe_close(conn) ⇒ Object



703
704
705
706
707
# File 'lib/pg_pipeline/pool.rb', line 703

def safe_close(conn)
  conn.close unless conn.finished?
rescue StandardError
  nil
end

.sanitize_pinned_connection(conn) ⇒ Object



685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
# File 'lib/pg_pipeline/pool.rb', line 685

def sanitize_pinned_connection(conn)
  raise ConnectionLostError, "pinned connection is closed" if conn.finished?
  raise ConnectionLostError, "pinned connection is bad" unless conn.status == PG::CONNECTION_OK

  case conn.transaction_status
  when PG::PQTRANS_IDLE
    nil
  when PG::PQTRANS_INTRANS, PG::PQTRANS_INERROR
    conn.exec("ROLLBACK")
  else
    raise ConnectionLostError,
          "pinned connection returned in unsafe transaction state #{conn.transaction_status}"
  end

  conn.exec("DISCARD ALL")
  true
end

.select_driver(drivers, rr) ⇒ Object



675
676
677
678
679
# File 'lib/pg_pipeline/pool.rb', line 675

def select_driver(drivers, rr)
  slot = [rr]
  driver = select_driver_into(drivers, rr, slot)
  [driver, slot[0]]
end

.select_driver_into(drivers, rr, slot) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
# File 'lib/pg_pipeline/pool.rb', line 645

def select_driver_into(drivers, rr, slot)
  size = drivers.length
  if size.zero?
    slot[0] = rr
    return nil
  end

  start = rr % size
  best = nil
  best_index, best_load, offset = 0, 0, 0

  while offset < size
    index = start + offset
    index -= size if index >= size
    driver = drivers[index]
    offset += 1
    next unless driver.available?

    load = driver.load
    next unless best.nil? || load < best_load

    best = driver
    best_index = index
    best_load = load
  end

  slot[0] = best ? (best_index + 1) % size : rr
  best
end