Class: SiteConnectionManager

Inherits:
ResourcePool
  • Object
show all
Defined in:
lib/polyphony/http/client/site_connection_manager.rb

Overview

HTTP site connection pool

Constant Summary collapse

SECURE_OPTS =
{ secure: true, alpn_protocols: ['h2', 'http/1.1'] }.freeze

Instance Method Summary collapse

Constructor Details

#initialize(uri_key) ⇒ SiteConnectionManager

Returns a new instance of SiteConnectionManager.



11
12
13
14
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 11

def initialize(uri_key)
  @uri_key = uri_key
  super(limit: 4)
end

Instance Method Details

#acquireObject

def method_missing(sym, *args)

raise "Invalid method #{sym}"

end



20
21
22
23
24
25
26
27
28
29
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 20

def acquire
  Thread.current.agent.ref
  prepare_first_connection if @size.zero?
  super
ensure
  Thread.current.agent.unref
  # The size goes back to 0 only in case existing connections get into an
  # error state and then get discarded
  @state = nil if @size == 0
end

#connectObject



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 76

def connect
  socket = create_socket
  protocol = socket_protocol(socket)
  case protocol
  when :http1
    HTTP1Adapter.new(socket)
  when :http2
    HTTP2Adapter.new(socket)
  else
    raise "Unknown protocol #{protocol.inspect}"
  end
end

#create_first_connectionObject



42
43
44
45
46
47
48
49
50
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 42

def create_first_connection
  @first_connection_queue = []
  # @first_connection_queue << Fiber.current

  adapter = connect
  @state = adapter.protocol
  send(:"setup_#{@state}_allocator", adapter)
  dequeue_first_connection_waiters
end

#create_socketObject



99
100
101
102
103
104
105
106
107
108
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 99

def create_socket
  case @uri_key[:scheme]
  when 'http'
    Polyphony::Net.tcp_connect(@uri_key[:host], @uri_key[:port])
  when 'https'
    Polyphony::Net.tcp_connect(@uri_key[:host], @uri_key[:port], SECURE_OPTS)
  else
    raise "Invalid scheme #{@uri_key[:scheme].inspect}"
  end
end

#dequeue_first_connection_waitersObject



69
70
71
72
73
74
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 69

def dequeue_first_connection_waiters
  return unless @first_connection_queue

  @first_connection_queue.each(&:schedule)
  @first_connection_queue = nil
end

#prepare_first_connectionObject



31
32
33
34
35
36
37
38
39
40
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 31

def prepare_first_connection
  case @state
  when nil
    @state = :first_connection
    create_first_connection
  when :first_connection
    @first_connection_queue << Fiber.current
    suspend
  end
end

#setup_http1_allocator(adapter) ⇒ Object



52
53
54
55
56
57
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 52

def setup_http1_allocator(adapter)
  @size += 1
  adapter.extend ResourceExtensions
  @stock << adapter
  @allocator = proc { connect }
end

#setup_http2_allocator(adapter) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 59

def setup_http2_allocator(adapter)
  @adapter = adapter
  @limit = 20
  @size += 1
  stream_adapter = adapter.allocate_stream_adapter
  stream_adapter.extend ResourceExtensions
  @stock << stream_adapter
  @allocator = proc { adapter.allocate_stream_adapter }
end

#socket_protocol(socket) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/polyphony/http/client/site_connection_manager.rb', line 89

def socket_protocol(socket)
  if socket.is_a?(OpenSSL::SSL::SSLSocket) && socket.alpn_protocol == 'h2'
    :http2
  else
    :http1
  end
end