状態の種類
- start
- v6c ... IPv6アドレスで接続開始
- v4w ... IPv6アドレスの名前解決を待機 (Resolution Delay)
- v4c ... IPv4アドレスで接続開始
- v46c ... IPv6 / IPv4アドレスのいずれかで接続開始
- v46w ... 接続確立またはIPv6 / IPv4アドレスのいずれかの名前解決を待機
- success
- failure
- timeout
扱うリソースなど
- Local addrinfos ... 接続ソケットにbindするaddrinfos (オプショナル)
- Local addrinfo ... 接続ソケットにbindするaddrinfo (オプショナル)
- Hostname resolution queue ... 名前解決済みのaddrinfos (を格納するキュー)
- Selectable addrinfos ... 接続に使用できるaddrinfos
- Selectable addrinfo ... 接続に使用できるaddrinfo
- Connecting addrinfo ... 接続に使用するaddrinfo
- Connecting sockets ... 接続中の全ソケット
- Connecting socket ... 接続中のソケット
- Connectable sockets ... 接続可能になった全ソケット (接続可能を通知する)
- Connectable socket ... 接続可能になったソケット
- Connected socket ... 接続済みのソケット
- Last error ... 最後に保存したエラー
フラグ
- retryable ... startで名前解決の待機をリトライ可能か
タイムアウト時間など
- Resolv timeout expires at ... 名前解決のタイムアウト時間 (オプショナル)
- Connect timeout expires at ... 接続のタイムアウト時間 (オプショナル)
- Resolution delay expires at ... v4wのタイムアウト時間
- Connection attempt delay expires at ... 現在の接続のタイムアウト時間 = 次の接続を開始できるようになる時間
case start
to
- v6c
- v4w
- failure
- timeout
do
Local addrinfos = Addrinfo.getaddrinfo
case リモートホストまたはローカルホストがIPアドレス
addrinfo = Addrinfo.getaddrinfo
Selectable addrinfos.push Selectable addrinfo
case IPv6 addrinfo
-> v6c
case IPv4 addrinfo
-> v4c
case リモートホストとローカルホストがドメイン名
Thread.new { IPv6 Addrinfo.getaddrinfo }
Thread.new { IPv4 Addrinfo.getaddrinfo }
while 次のstateが決定するまで
select([Hostname resolution rpipe], Resolv timeout expires at)
case Resolv timeout expires at 超過
-> timeout
case v6名前解決
Selectable addrinfo = Hostname resolution queue.pop
Selectable addrinfos.push Selectable addrinfo
-> v6c
case v4名前解決
Selectable addrinfo = Hostname resolution queue.pop
Selectable addrinfos.push Selectable addrinfo
-> v4w
case 名前解決エラー
case retryable: true
retry
case retryable: false
Last error = エラー
-> failure
case v4w
from
- start
condition
- selectの返り値:
- Resolution delay expires at 超過
- v6名前解決
- 名前解決エラー
to
- v4c
- v46c
do
select([Hostname resolution rpipe], Resolution delay expires at)
case Resolution delay expires at 超過
-> v4c
case v6アドレス解決
Selectable addrinfo = Hostname resolution queue.pop
Selectable addrinfos.push Selectable addrinfo
-> v46c
case 名前解決エラー
-> v46c
case v6c, v4c, v46c
from
- start
- v4w
- v46w
to
- v46c
- v46w
- success
- failure
do
Connecting addrinfo = Selectable addrinfos.pop
Connecting socket = Socket.new(Connecting addrinfo)
case Local addrinfos: any
case Connecting addrinfoと同じアドレスファミリのLocal addrinfoがある
Local addrinfo = Local addrinfos.pick
Connecting socket.bind Local addrinfo
以下へ進む
case Connecting addrinfoと同じアドレスファミリのLocal addrinfoがない
case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: closed
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened
# 次のループで接続か名前解決を待つ
# Connecting socketsがあるうちはResolv timeout expires at は考慮しない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed
# 次のループで接続を待つ
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened
case Resolv timeout expires at: 設定あり && Resolv timeout expires at 超過
-> timeout
case それ以外
# 次のループで名前解決を待つ
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed
-> failure
case Local addrinfos: empty
以下へ進む
Connection attempt delay expires at = 現在のクロック時間 + Connection Attempt Delay
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed
connect
case それ以外
connect_nonblock
以下へ進む
case 接続に成功
-> success
case 接続中
Connecting sockets.add Connecting socket
-> v46w
case SystemCallError
Last error = SystemCallError
case Selectable addrinfos: any && Connecting Sockets: any && Hostname resolution queue: opened
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting Sockets: any && Hostname resolution queue: closed
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting Sockets: empty && Hostname resolution queue: opened
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: any && Connecting Sockets: empty && Hostname resolution queue: closed
# 次のループで別のSelectable addrinfoを試す
-> v46c
case Selectable addrinfos: empty && Connecting Sockets: any && Hostname resolution queue: opened
# 次のループで名前解決か接続を待つ。名前解決した場合はさらに次のループでv46cへ、接続した場合はさらに次のループでsuccessへ
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting Sockets: any && Hostname resolution queue: closed
# 次のループで接続を待つ
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting Sockets: empty && Hostname resolution queue: opened
case Resolv timeout expires at: 設定あり && Resolv timeout expires at 超過
-> timeout
case それ以外
# 次のループで名前解決を待つ
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting Sockets: empty && Hostname resolution queue: closed
-> failure
case v46w
from
- v6c
- v4c
- v46c
- v46w
to
- v46c
- v46w
- success
- timeout
do
case Connect timeout expires at 超過
-> timeoeut
case Connect timeout expires at 超過ではない
以下へ進む
select([Hostname resolution rpipe], Connecting sockets, Connection attempt delay expires at)
case Connectable sockets: any
while (Connectable socket = Connectable sockets.pop)
Connecting sockets.remove Connectable socket
getsockopt(<接続エラーの確認>)
case エラーなし
Connected socket = Connectable socket
-> success
case エラーあり
case Connectable sockets: any
retry
case Connectable sockets: empty
以下に進む
case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened
# 次のループでConnection attempt delay expires atを超過するまで接続か名前解決を待つ
# 接続しなかった場合、名前解決してもしなくてもさらに次のループでv46cへ
-> v46w
case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: closed
# 次のループでConnection attempt delay expires atを超過するまで接続を待つ
# 接続しなかった場合はさらに次のループでv46cへ
-> v46w
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened
# 次のループでConnection attempt delay expires atを超過するまで名前解決を待つ
# 名前解決してもしなくてもさらに次のループでv46cへ
-> v46w
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed
# 次のループでConnection attempt delay expires atを超過するまで名前解決を待つ
# さらに次のループでv46cへ
-> v46w
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened
# あとは接続か名前解決をひたすら待つことしかできない
# Connecting socketsがあるうちはResolv timeout expires at は考慮しない
-> v46w
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed
# あとは接続をひたすら待つことしかできない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened
case Resolv timeout expires at: 設定あり && Resolv timeout expires at 超過
-> timeout
case それ以外
# あとは名前解決をひたすら待つことしかできない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed
-> failure
case 名前解決
Selectable addrinfo = Hostname resolution queue.pop
Selectable addrinfos.push Selectable addrinfo
# 次のループでConnection attempt delay expires atを超過するまで待ち、さらに次のループでv46cへ
-> v46w
case 名前解決エラー
# 次のループでConnection attempt delay expires atを超過するまで待ち、さらに次のループでリソースの状態によって分岐
-> v46w
case Connection attempt delay expires at 超過
case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened
-> v46c
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened
-> v46c
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened
-> v46c
case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed
-> v46c
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened
# あとは接続か名前解決をひたすら待つことしかできない
# Connecting socketsがあるうちはResolv timeout expires at は考慮しない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened
case Resolv timeout expires at: 設定あり && Resolv timeout expires at 超過
-> timeout
case それ以外
# あとは名前解決をひたすら待つことしかできない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed
# あとは接続をひたすら待つことしかできない
Connection attempt delay expires at = nil
-> v46w
case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed
-> failure
case success
from
- v46w
do
cleanup
return Connected socket
case failure
from
- start
do
cleanup
raise Last error
case timeout
from
- start
do
cleanup
raise Errno::ETIMEDOUT, 'user specified timeout'
-
-
Save shioimm/fbb09f103caf0812137c5c67ffa14eb6 to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment