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



542
543
544
545
546
547
548
549
550
551
# File 'lib/pg_pipeline/pool.rb', line 542

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



600
601
602
# File 'lib/pg_pipeline/pool.rb', line 600

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

.nonnegative_integer!(value, name) ⇒ Object



553
554
555
556
557
558
559
560
# File 'lib/pg_pipeline/pool.rb', line 553

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



533
534
535
536
537
538
539
540
# File 'lib/pg_pipeline/pool.rb', line 533

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



622
623
624
625
626
# File 'lib/pg_pipeline/pool.rb', line 622

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

.sanitize_pinned_connection(conn) ⇒ Object



604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/pg_pipeline/pool.rb', line 604

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



594
595
596
597
598
# File 'lib/pg_pipeline/pool.rb', line 594

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



562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
# File 'lib/pg_pipeline/pool.rb', line 562

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 = 0
  best_load = 0
  offset = 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