Slide 1

Slide 1 text

.BLJOH5$14PDLFUOFX)BQQZ .JTBLJ4IJPJ !TIJPJNN!DPF@!DPFCTLZTPDJBM   3VCZ,BJHJ

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

QQTFMG ɹ.JTBLJ4IJPJ ɹ.FNCFSPG"TBLVTBSC ɹ3BJMTBQQMJDBUJPOEFWFMPQFSBU4.4$P -UE ɹ3VCZDPNNJUUFSTJODF/PW ɹ#PSOJO,PDIJ OFYUUP&IJNF !TIJPJNN (JU)VC !DPF@ FY5XJUUFS !DPFCTLZTPDJBM #MVFTLZ QQTFMG 8FSFIFSF *NGSPNIFSF

Slide 4

Slide 4 text

.BLJOH5$14PDLFUOFX)BQQZ

Slide 5

Slide 5 text

-FUTHPCBDLJOUJNF.BZ 

Slide 6

Slide 6 text

 -FUTHPCBDLJOUJNF.BZ  3VCZ,BJHJ%BZ

Slide 7

Slide 7 text

"OBEWFOUVSFPG)BQQZ&ZFCBMMT IUUQTSVCZLBJHJPSHQSFTFOUBUJPOTDPF@IUNMEBZ

Slide 8

Slide 8 text

"OBEWFOUVSFPG)BQQZ&ZFCBMMT *QSFTFOUFEUIFTUPSZPGJOUSPEVDJOH )BQQZ&ZFCBMMT7FSTJPO EF fi OFEJO3'$  JOUP4PDLFUUDQBU3VCZ,BJHJ #FGPSFEJWJOHJOUP.BLJOH5$14PDLFUOFX)BQQZ  *EMJLFUPCSJF fl ZSFDBQJU

Slide 9

Slide 9 text

"OBEWFOUVSFPG)BQQZ&ZFCBMMT 5IF3VCZTPDLFUMJCSBSZQSPWJEFTNFUIPETGPSSFUVSOJOH BDMJFOUTPDLFUDPOOFDUFEUPBTQFDJ fi FETFSWFSWJB5$1  0OFJT4PDLFUUDQ JNQMFNFOUFEJO3VCZ  BOEUIFPUIFSJT5$14PDLFUOFX JNQMFNFOUFEJO$ SFUVSOTBDMJFOUTPDLFU 4FSWFS $POOFDUJPOFTUBCMJTIFE 4PDLFUUDQ 5$14PDLFUOFX TPDLFU"OFOEQPJOUGPSDPNNVOJDBUJPOCFUXFFOIPTUTPWFSBOFUXPSL

Slide 10

Slide 10 text

*GUIFEFTUJOBUJPOTFSWFSIBECPUI*1WBOE*1WBEESFTTFT  UIFTFNFUIPETQSFWJPVTMZQSPDFTTFETFRVFOUJBMMZ 'PSFYBNQMF 3FTPMWF*1WBEESFTTFT fi STU UIFO*1WBEESFTTFT "GUFSCPUIXFSFSFTPMWFE BUUFNQUDPOOFDUJOHUPUIF*1WBEESFTTFT fi STU BOEGBMMCBDLUPUIF*1WBEESFTTFTPOMZJGUIFZGBJMFE *1W *1W FH $POOFDUJPOGBJMFEXJUI*1W "OBEWFOUVSFPG)BQQZ&ZFCBMMT 4FSWFS 4PDLFUUDQ 5$14PDLFUOFX 4UBSUBDPOOFDUJPOBUUFNQUUP*1W 4UBSUBDPOOFDUJPOBUUFNQUUP*1W $POOFDUJPOFTUBCMJTIFEXJUI*1W

Slide 11

Slide 11 text

*G*1WOBNFSFTPMVUJPOGBJMFEPSBDPOOFDUJPOUPUIFTFSWFS DPVMEO`UCFFTUBCMJTIFEJOUIJTDBTF  UIFSFXBTBOJTTVFXIFSFJUDPVMEO`UJNNFEJBUFMZGBMMCBDLUP *1W *1W *1W 4FSWFS 5IFBUUFNQUDPOUJOVFT $BOOPUTUBSUBOFXBUUFNQUUP*1W "OBEWFOUVSFPG)BQQZ&ZFCBMMT FH 4UBSUBDPOOFDUJPOBUUFNQUUP*1W 4PDLFUUDQ 5$14PDLFUOFX

Slide 12

Slide 12 text

)BQQZ&ZFCBMMT7FSTJPO )&W JTBOBMHPSJUINEFTJHOFEUP PWFSDPNFUIJTJTTVFBOEBDIJFWFNPSFF ff i DJFOUDPOOFDUJPOT 8JUI)&W IPTUOBNFSFTPMVUJPOBOEDPOOFDUJPOBUUFNQUT  XIJDIXFSFQSFWJPVTMZQFSGPSNFEPOFBUBUJNF TFRVFOUJBMMZ  BSFOPXQFSGPSNFENVMUJQMFBUPODF JOQBSBMMFM *1W *1W 4FSWFS $POOFDUJPOFTUBCMJTIFEXJUIFBSMJFS "OBEWFOUVSFPG)BQQZ&ZFCBMMT FH 4UBSUBDPOOFDUJPOBUUFNQUUP*1W 4UBSUBDPOOFDUJPOBUUFNQUUP*1W 4PDLFUUDQ 5$14PDLFUOFX

Slide 13

Slide 13 text

"OPWFSWJFXPGIPX)&WXPSLTJT )PX)&WXPSLT %/4TFSWFS %FTUJOBUJPOTFSWFS 4PDLFUUDQ 5$14PDLFUOFX

Slide 14

Slide 14 text

'JSTU CPUI*1WBOE*1WIPTUOBNFSFTPMVUJPOBSFTUBSUFE TJNVMUBOFPVTMZJOQBSBMMFM %/4TFSWFS )PX)&WXPSLT %FTUJOBUJPOTFSWFS 4PDLFUUDQ 5$14PDLFUOFX 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT

Slide 15

Slide 15 text

"TTPPOBTFJUIFSPOFDPNQMFUFT TUBSUBDPOOFDUJPO BUUFNQUUPPOFPGUIFBEESFTTFTPCUBJOFEGSPNUIBUSFTVMU %/4TFSWFS )PX)&WXPSLT %FTUJOBUJPOTFSWFS 4PDLFUUDQ 5$14PDLFUOFX 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT 5PBSFTPMWFE*1WBEESFTT "OTXFS*1WBEESFTTFT fi STU

Slide 16

Slide 16 text

)PXFWFS )&WQSJPSJUJ[FTDPOOFDUJPOTPWFS*1W*GUIF*1W BEESFTTFTBSFSFTPMWFE fi STU XBJUVQUPNTGPSUIF*1W SFTPMVUJPOUPDPNQMFUFCFGPSFTUBSUJOHBDPOOFDUJPOBUUFNQU )PX)&WXPSLT %/4TFSWFS %FTUJOBUJPOTFSWFS 4PDLFUUDQ 5$14PDLFUOFX 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT "OTXFS*1WBEESFTTFT fi STU 8BJUNTGPS*1WOBNFSFTPMVUJPO

Slide 17

Slide 17 text

5IJTNTEFMBZJTDBMMFE3FTPMVUJPO%FMBZ )PX)&WXPSLT %/4TFSWFS %FTUJOBUJPOTFSWFS 4PDLFUUDQ 5$14PDLFUOFX 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT "OTXFS*1WBEESFTTFT fi STU 8BJUNTGPS*1WOBNFSFTPMVUJPO 3FTPMVUJPO%FMBZ

Slide 18

Slide 18 text

"GUFSTUBSUJOHBDPOOFDUJPOBUUFNQU XBJUVQUPNTGPS BDPOOFDUJPOUPCFFTUBCMJTIFE 4PDLFUUDQ 5$14PDLFUOFX )PX)&WXPSLT %FTUJOBUJPOTFSWFS 5PBSFTPMWFEBEESFTT" 8BJUNTGPSBDPOOFDUJPOFTUBCMJTIFE

Slide 19

Slide 19 text

5IJTNTEFMBZJTDBMMFE$POOFDUJPO"UUFNQU%FMBZ 4PDLFUUDQ 5$14PDLFUOFX $POOFDUJPO"UUFNQU%FMBZ )PX)&WXPSLT %FTUJOBUJPOTFSWFS 8BJUNTGPSBDPOOFDUJPOFTUBCMJTIFE 5PBSFTPMWFEBEESFTT"

Slide 20

Slide 20 text

*GUIFDPOOFDUJPOJTOPUFTUBCMJTIFEEVSJOH$POOFDUJPO "UUFNQU%FMBZ TUBSUBOFXBUUFNQUUPBOPUIFSBEESFTT $POUJOVFTUBSUJOHOFXDPOOFDUJPOBUUFNQUTFWFSZNT VOUJMBDPOOFDUJPOJTTVDDFTTGVMMZFTUBCMJTIFEPS BMMDBOEJEBUFBEESFTTFTBSFFYIBVTUFE 4PDLFUUDQ 5$14PDLFUOFX )PX)&WXPSLT %FTUJOBUJPOTFSWFS 5PBSFTPMWFEBEESFTT" "GUFSNT UPBSFTPMWFEBEESFTT#

Slide 21

Slide 21 text

*GBOZPGUIFDPOOFDUJPOTJTTVDDFTTGVMMZFTUBCMJTIFE  DBODFMBMMUIFPUIFSDPOOFDUJPOBUUFNQUT 5IFDPOOFDUJPOBUUFNQUUP"JTDBODFMFE $POOFDUJPOFTUBCMJTIFEXJUI# )PX)&WXPSLT 4PDLFUUDQ 5$14PDLFUOFX %FTUJOBUJPOTFSWFS 5PBSFTPMWFEBEESFTT" "GUFSNT UPBSFTPMWFEBEESFTT#

Slide 22

Slide 22 text

5IJTJTBTUBUFUSBOTJUJPOEJBHSBNUIBUSFQSFTFOUTUIF fl PXPG)&W "TUBUFUSBOTJUJPOEJBHSBNPG)&W WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ʜBTUBUF ʜUSBOTJUJPO

Slide 23

Slide 23 text

"TUBUFUSBOTJUJPOEJBHSBNPG)&W "U3VCZ,BJHJMBTUZFBS *UBMLFEBCPVUIPXUIJTEJBHSBN XBTUSBOTMBUFEJOUPDPEFBOEJNQMFNFOUFEJO4PDLFUUDQ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ʜBTUBUF ʜUSBOTJUJPO

Slide 24

Slide 24 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end 5IFJNQMFNFOUBUJPOPG4PDLFUUDQ )FSFJTBCSJFGPWFSWJFXPG4PDLFUUDQXJUI)&W JNQMFNFOUBUJPO

Slide 25

Slide 25 text

5IFTUBUFUSBOTJUJPO def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD 5IFTUBUFUSBOTJUJPOEJBHSBNJTSFQSFTFOUFE CZDBMMJOHBDBTFTUBUFNFOUJOTJEF,FSOFMMPPQ

Slide 26

Slide 26 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end 5IFDVSSFOUTUBUFJTTUPSFEJOBWBSJBCMFTUBUF TUBUF"WBSJBCMFUPTUPSFUIFDVSSFOUTUBUF 5IFDVSSFOUTUBUF 5IFTUBUFUSBOTJUJPO

Slide 27

Slide 27 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end 5IFQSPDFTTPQFSBUFTBTGPMMPXT &YFDVUFUIFQSFEF fi OFEQSPDFTTJOHGPSUIFDVSSFOUTUBUF  ➡︎ 4FUUIFOFYUTUBUF ➡︎ 1SPDFFEUPUIFOFYUMPPQJUFSBUJPO 5IFBDUJPOTQFSGPSNFEGPSFBDITUBUF TUBUF"WBSJBCMFUPTUPSFUIFDVSSFOUTUBUF 5IFDVSSFOUTUBUF 5IFTUBUFUSBOTJUJPO

Slide 28

Slide 28 text

5IFTUBUFUSBOTJUJPO def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end "UUIFTUBSUPGUIFNFUIPE UIFWBSJBCMFTUBUFJT JOJUJBMJ[FEXJUIUIFJOJUJBMTUBUFTUBSU TUBSUBTBJOJUJBMTUBUF

Slide 29

Slide 29 text

5IFTUBUFTUBSU def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD *OUIF fi STUJUFSBUJPOPGUIFMPPQ  UIFQSPDFTTPGTUBSUJTFYFDVUFE

Slide 30

Slide 30 text

case state when :start # ... TUBSU'JSTU DSFBUFBOPCKFDUXJUI BQBJSPGQJQF SFUVSOWBMVFPG*0QJQF  BOEBRVFVF SFUVSOWBMVFPG2VFVFOFX  hostname_resolution_queue = HostnameResolutionQueue.new(resolving_family_names.size) 4UBSUIPTUOBNFSFTPMVUJPO def initialize(size) # ... @rpipe, @wpipe = IO.pipe @queue = Queue.new @mutex = Mutex.new end 5IFTUBUFTUBSU

Slide 31

Slide 31 text

case state when :start # ... hostname_resolution_threads.concat( resolving_family_names.map { |family| thread_args = [family, *hostname_resolution_args] thread = Thread.new(*thread_args) { |*thread_args| hostname_resolution(*thread_args) } Thread.pass thread } ) # ... TUBSU4QBXOBUISFBEGPSFBDIBEESFTTGBNJMZ #ZDBMMJOHUIFOBNFSFTPMVUJPONFUIPEJOFBDIDIJME UISFBE *1WBOE*1WOBNFSFTPMVUJPOTUBSUJOQBSBMMFM 5IFOBNFSFTPMVUJPONFUIPE 4QBXOBUISFBE 4UBSUIPTUOBNFSFTPMVUJPO hostname_resolution_queue = HostnameResolutionQueue.new(resolving_family_names.size) hostname_resolution_waiting = hostname_resolution_queue.waiting_pipe hostname_resolution_args = [host, port, hostname_resolution_queue] 5IFTUBUFTUBSU

Slide 32

Slide 32 text

case state when :start # ... hostname_resolution_threads.concat( resolving_family_names.map { |family| thread_args = [family, *hostname_resolution_args] thread = Thread.new(*thread_args) { |*thread_args| hostname_resolution(*thread_args) } Thread.pass thread } ) # ... 4UBSUIPTUOBNFSFTPMVUJPO hostname_resolution_queue = HostnameResolutionQueue.new(resolving_family_names.size) hostname_resolution_waiting = hostname_resolution_queue.waiting_pipe hostname_resolution_args = [host, port, hostname_resolution_queue] TUBSU1BTTUIFPCKFDUDSFBUFEFBSMJFSUIBUIPMETUIFQJQF BOEUIFRVFVF BMPOHXJUIPUIFSFMFNFOUTOFDFTTBSZGPS OBNFSFTPMVUJPOUPUIFNFUIPE BTBSHVNFOUT  5IFTUBUFTUBSU

Slide 33

Slide 33 text

def self.hostname_resolution(family, host, port, hostname_resolution_queue) begin resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) rescue => e # ... end end TUBSU)FSFJTUIFJNQMFNFOUBUJPOPG UIFOBNFSFTPMVUJPONFUIPE 5IFTUBUFTUBSU

Slide 34

Slide 34 text

def self.hostname_resolution(family, host, port, hostname_resolution_queue) begin resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) rescue => e # ... end end TUBSU$BMM"EESJOGPHFUBEESJOGPXIJDIQFSGPSNT IPTUOBNFSFTPMVUJPO 'PSIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU

Slide 35

Slide 35 text

def self.hostname_resolution(family, host, port, hostname_resolution_queue) begin resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) rescue => e # ... end end TUBSU0ODFIPTUOBNFSFTPMVUJPOJTDPNQMFUF  QVTIUIFPCUBJOFEBEESFTTFTJOUPUIFRVFVFTIBSFE CFUXFFOUIFDIJMEUISFBETBOEUIFNBJOUISFBE def add_resolved(family, resolved_addrinfos) @mutex.synchronize do @queue.push [family, resolved_addrinfos] @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED end end 5IFTUBUFTUBSU

Slide 36

Slide 36 text

def self.hostname_resolution(family, host, port, hostname_resolution_queue) begin resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) rescue => e # ... end end TUBSU"OEJUJTOFDFTTBSZUPOPUJGZUIFNBJOUISFBE UIBUOBNFSFTPMVUJPOIBTDPNQMFUFEJOUIFDIJMEUISFBE def add_resolved(family, resolved_addrinfos) @mutex.synchronize do @queue.push [family, resolved_addrinfos] @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED end end 5IFTUBUFTUBSU

Slide 37

Slide 37 text

def self.hostname_resolution(family, host, port, hostname_resolution_queue) begin resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) rescue => e # ... end end TUBSU5PEPUIJT XSJUFUIFOPUJ fi DBUJPOUPUIFXSJUFFOE PGBQJQFUIBUJTBMTPTIBSFEXJUIUIFNBJOUISFBE def add_resolved(family, resolved_addrinfos) @mutex.synchronize do @queue.push [family, resolved_addrinfos] @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED end end 5IFTUBUFTUBSU

Slide 38

Slide 38 text

case state when :start # Create child threads and call Socket.hostname_resolution hostname_resolved, _, = IO.select( # ... (hostname_resolution_waiting, nil, nil, nil) TUBSU*OUIFNBJOUISFBE *0TFMFDUJTDBMMFE BGUFSTQBXOJOHUIFDIJMEUISFBET 4UBSUIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU

Slide 39

Slide 39 text

case state when :start # Create child threads and call Socket.hostname_resolution hostname_resolved, _, = IO.select( # ... (hostname_resolution_waiting, nil, nil, nil) TUBSU5IFSFBEFOEPGUIFQJQFTIBSFEXJUI UIFDIJMEUISFBEJTQBTTFEBTBOBSHVNFOUUP*0TFMFDU 4UBSUIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU 5IFSFBEFOEPGUIFQJQF

Slide 40

Slide 40 text

case state when :start # Create child threads and call Socket.hostname_resolution hostname_resolved, _, = IO.select( # ... (hostname_resolution_waiting, nil, nil, nil) TUBSU8IFOFJUIFSUIF*1WPS*1WOBNFSFTPMVUJPO DPNQMFUFTJOUIFDIJMEUISFBE BOPUJ fi DBUJPOJTTFOU UISPVHIUIJTQJQF6OUJMUIBUOPUJ fi DBUJPOBSSJWFT  *0TFMFDUXJMMCMPDLJOEF fi OJUFMZ #MPDLQSPDFTTJOH 4UBSUIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU 5IFOPUJ fi DBUJPOGSPNUIFDIJMEUISFBEBSSJWFTIFSF

Slide 41

Slide 41 text

case state when :start # Create child threads and call Socket.hostname_resolution hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next TUBSU8IFOBOPUJ fi DBUJPOBSSJWFTUISPVHIUIFQJQF BOE*0TFMFDUVOCMPDLT UIFOSFUSJFWFUIFSFTPMWFE BEESFTTFT (FUUIFSFTVMUPGUIFIPTUOBNFSFTPMVUJPO 4UBSUIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU (hostname_resolution_waiting, nil, nil, nil)

Slide 42

Slide 42 text

case state when :start # Create child threads and call Socket.hostname_resolution hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next TUBSU*GUIFSFTPMWFEBEESFTTFTBSF*1W  USBOTJUJPOUPWX*GJUJT*1W USBOTJUJPOUPWD %FUFSNJOFUIFOFYUTUBUF (POFYU 4UBSUIPTUOBNFSFTPMVUJPO 5IFTUBUFTUBSU (hostname_resolution_waiting, nil, nil, nil)

Slide 43

Slide 43 text

5IFTUBUFWX def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD WXJTTUBUFGPS3FTPMVUJPO%FMBZ  XIJDIXBJUTVQUPNTGPSPOMZ*1WOBNFSFTPMVUJPO

Slide 44

Slide 44 text

case state when :v4w ipv6_resolved, _, = IO.select( # ... WX1BTTUIFSFBEFOEPGUIFQJQFUP*0TFMFDU UPCMPDLUIFQSPDFTT (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) 8BJUGPSNTGPS*1WOBNFSFTPMVUJPO 5IFTUBUFWX 5IFSFBEFOEPGUIFQJQF #MPDLQSPDFTTJOH

Slide 45

Slide 45 text

case state when :v4w ipv6_resolved, _, = IO.select( # ... WX1BTTNTBT3FTPMVUJPO%FMBZUPUIFUJNFPVU BSHVNFOU*0TFMFDUXJMMVOCMPDLFJUIFSXIFOUIF*1W OBNFSFTPMVUJPODPNQMFUFTPSXIFOUIFNTUJNFPVU FMBQTFT (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) 8BJUGPSNTGPS*1WOBNFSFTPMVUJPO 5IFTUBUFWX #MPDLQSPDFTTJOH NTGPS3FTPMVUJPO%FMBZ 5IFSFBEFOEPGUIFQJQF

Slide 46

Slide 46 text

case state when :v4w ipv6_resolved, _, = IO.select( if ipv6_resolved family_name, res = hostname_resolution_queue.get selectable_addrinfos.add(family_name, res) unless res.is_a? E state = :v46c else state = :v4c end next WX"GUFS*0TFMFDUVOCMPDLTBOEJG*1WJTSFTPMWFE XJUIJONT USBOTJUJPOUPWD *GOPU USBOTJUJPOUPWD (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) Exception (POFYU %FUFSNJOFUIFOFYUTUBUF 5IFTUBUFWX 8BJUGPSNTGPS*1WOBNFSFTPMVUJPO

Slide 47

Slide 47 text

5IFTUBUFWDWDWD def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD WD WD BOEWDBSFUIFTUBUF UPTUBSUBOFXDPOOFDUJPOBUUFNQU

Slide 48

Slide 48 text

case state when :v6c, :v4c, v46c # ... addrinfo = selectable_addrinfos.get # ... socket = Socket.new( # ... result = socket.connect_nonblock(addrinfo, exception: false) # ... (addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) WDWDWD3FUSJFWFPOFPGBWBJMBCMFBEESFTTFT GPSUIFDPOOFDUJPOBOETUBSUBOPOCMPDLJOHDPOOFDUJPO 4UBSUBOFXDPOOFDUJPOBUUFNQU 3FUSJFWFBOBWBJMBCMFBEESFTT 4UBSUBDPOOFDUJPOBUUFNQU 5IFTUBUFWDWDWD

Slide 49

Slide 49 text

case state when :v6c, :v4c, v46c # ... addrinfo = selectable_addrinfos.get # ... socket = Socket.new( # ... result = socket.connect_nonblock(addrinfo, exception: false) # ... connecting_sockets.add(socket, addrinfo) state = :v46w # ... next (addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) WDWDWD5IFOTUPSFUIFTPDLFUVTFEGPS UIFDPOOFDUJPOBUUFNQU BOEUSBOTJUJPOUPWX (POFYU 4FUUIFOFYUTUBUF 4UPSFUIFTPDLFU 4UBSUBOFXDPOOFDUJPOBUUFNQU 5IFTUBUFWDWDWD

Slide 50

Slide 50 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD *OWX UIFQSPDFTTXBJUTGPSUIFDPOOFDUJPOUPCF FTUBCMJTIFE0S JGUIFPUIFSBEESFTTGBNJMZJTTUJMMSFTPMWJOH BUUIJTQPJOU JUBMTPXBJUTGPSUIBUSFTPMVUJPOUPDPNQMFUF 5IFTUBUFWX

Slide 51

Slide 51 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) WX5IFQSPDFTTJOHJTCMPDLFEXJUI*0TFMFDUBHBJO 5IJT*0TFMFDUNPOJUPSTCPUIUIFSFBEFOEPGUIFQJQF BOEBMMUIFTPDLFUTDVSSFOUMZBUUFNQUJOHUPDPOOFDU 8BJUGPSUIFDPOOFDUJPOTUBUFUPCFDPO fi SNFEBOEOBNFSFTPMVUJPOUPDPNQMFUF 5IFTUBUFWX 5IFTPDLFUTBUUFNQUJOHUPDPOOFDU 5IFSFBEFOEPGUIFQJQF #MPDLQSPDFTTJOH

Slide 52

Slide 52 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) 8BJUGPSUIFDPOOFDUJPOTUBUFUPCFDPO fi SNFEBOEOBNFSFTPMVUJPOUPDPNQMFUF #MPDLQSPDFTTJOH WX5IFUJNFPVUBSHVNFOUJTTFUUPNT 5IJTSFQSFTFOUT$POOFDUJPO"UUFNQU%FMBZŠ UIFXBJUJOHUJNFCFUXFFOTUBSUJOHUIFQSFWJPVT DPOOFDUJPOBUUFNQUBOETUBSUJOHUIFOFYUPOF NTGPS$POOFDUJPO"UUFNQU%FMBZ 5IFTPDLFUTBUUFNQUJOHUPDPOOFDU 5IFSFBEFOEPGUIFQJQF 5IFTUBUFWX

Slide 53

Slide 53 text

5IFTUBUFWX case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) 8BJUGPSUIFDPOOFDUJPOTUBUFUPCFDPO fi SNFEBOEOBNFSFTPMVUJPOUPDPNQMFUF #MPDLQSPDFTTJOH NTGPS$POOFDUJPO"UUFNQU%FMBZ 5IFTPDLFUTBUUFNQUJOHUPDPOOFDU 5IFSFBEFOEPGUIFQJQF WX*0TFMFDUVOCMPDLTXIFOFJUIFSBOBNFSFTPMVUJPO DPNQMFUJPOOPUJ fi DBUJPOBSSJWFTPOUIFSFBEFOEPGUIFQJQF  BOZPGUIFTPDLFUTDVSSFOUMZBUUFNQUJOHUPDPOOFDUCFDPNF XSJUBCMF PSUIFNTUJNFPVUFMBQTFT

Slide 54

Slide 54 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? # ... else # ... end # ... next (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) WX0ODF*0TFMFDUVOCMPDLT UIFOFYUTUBUFJT EFUFSNJOFECBTFEPOUIFSFBTPOJUXBTVOCMPDLFE (POFYU %FUFSNJOFUIFOFYUTUBUF 5IFJNQMFNFOUBUJPOPG4PDLFUUDQ WX 8BJUGPSUIFDPOOFDUJPOTUBUFUPCFDPO fi SNFEBOEOBNFSFTPMVUJPOUPDPNQMFUF *GUIF$POOFDUJPO"UUFNQU%FMBZUJNFTPVU

Slide 55

Slide 55 text

5IFJNQMFNFOUBUJPOPG4PDLFUUDQ def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD &WFOUVBMMZ POFPGUIFUFSNJOBMTUBUFT TVDDFTT GBJMVSF  PSUJNFPVU JTSFBDIFE5IFO4PDLFUUDQ fi OJTIFTCZ FJUIFSSFUVSOJOHUIFDPOOFDUFETPDLFUPSSBJTJOH BOFYDFQUJPO EFQFOEJOHPOUIFTJUVBUJPO

Slide 56

Slide 56 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then Start hostname resolution when :v4w then Wait for 50ms for IPv6 name resolution when :v6c, :v4c, :v46c then Start a new connection attempt when :v46w then Wait for the connection state to be confirmed and name resolution to complete when :success then Return the successfully connected socket when :failure then Raise an exception when :timeout then Raise a timeout exception end end end WD GBJMVSF TVDDFTT TUBSU WX UJNFPVU WX WD WD 5IFJNQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W JTOPXDPNQMFUF 5IFJNQMFNFOUBUJPOPG4PDLFUUDQ

Slide 57

Slide 57 text

5IJTDIBOHFXBTNFSHFEJOUP3VCZNBTUFSPO'FC  5IJTJTUIFTUPSZ*JOUSPEVDFEBU3VCZ,BJHJMBTUZFBS .FSHFE IUUQTHJUIVCDPNSVCZSVCZQVMM 5IJTXSBQTVQPVSSFWJFXPG"O"EWFOUVSFPG)BQQZ&ZFCBMMT

Slide 58

Slide 58 text

.BLJOH5$14PDLFUOFX)BQQZ /PX MFUTJOUSPEVDF)BQQZ&ZFCBMMT7FSTJPO JOUP5$14PDLFUOFX JNQMFNFOUFEJO$  VTJOHUIF4PDLFUUDQJNQMFNFOUBUJPOBTBSFGFSFODF

Slide 59

Slide 59 text

)PXFWFS

Slide 60

Slide 60 text

.BZ 

Slide 61

Slide 61 text

"DPODFSOSBJTFECZ!BLS .BZ 

Slide 62

Slide 62 text

"DPODFSOSBJTFECZ!BLS 5IFJNQMFNFOUBUJPOMPPLT FYDFTTJWFMZMJLFBTUBUFUSBOTJUJPO !BLS

Slide 63

Slide 63 text

"OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next (hostname_resolution_waiting, nil, nil, remaining) -FUTSFWJFXTUBSUBHBJO GPDVTJOHPOXIBUIBQQFOT BGUFS*0TFMFDUVOCMPDLTŠUIBUJT BGUFSFJUIFSUIF*1W PS*1WSFTPMVUJPODPNQMFUFT 4UBSUIPTUOBNFSFTPMVUJPO

Slide 64

Slide 64 text

case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next (hostname_resolution_waiting, nil, nil, remaining) 5IFOFYUTUBUFJTEFUFSNJOFECBTFEPOXIFUIFS UIFBEESFTTSFUSJFWFGSPNUIFRVFVFJT*1WPS*1W 4UBSUIPTUOBNFSFTPMVUJPO (FUUIFSFTVMU "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM %FUFSNJOFUIFOFYUTUBUF

Slide 65

Slide 65 text

case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next (hostname_resolution_waiting, nil, nil, remaining) 8IBUIBQQFOTJGCPUI*1WBOE*1WIBWF BMSFBEZDPNQMFUFEOBNFSFTPMVUJPOBUUIJTQPJOU 4UBSUIPTUOBNFSFTPMVUJPO "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM

Slide 66

Slide 66 text

case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next 4UBSUIPTUOBNFSFTPMVUJPO *1W *OUIJTDBTF UIFRVFVFIBT CPUI*1WBOE*1WBEESFTTFT (hostname_resolution_waiting, nil, nil, remaining) "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM *1W 5IFRVFVF

Slide 67

Slide 67 text

case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next 4UBSUIPTUOBNFSFTPMVUJPO 'PSFYBNQMF  JGUIF*1WBEESFTTFTBSFSFUSJFWFEGSPNUIFRVFVF  (hostname_resolution_waiting, nil, nil, remaining) "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM *1W *1W 5IFRVFVF 3FUSJFWF*1WBEESFTTPOMZ

Slide 68

Slide 68 text

case state when :start # ... hostname_resolved, _, = IO.select( # ... family_name, res = hostname_resolution_queue.get # ... state = case family_name when :ipv6 then :v6c when :ipv4 then :v4w end selectable_addrinfos.add(family_name, res) # ... next 4UBSUIPTUOBNFSFTPMVUJPO %FUFSNJOFUIBU*1WXBTSFTPMWFE fi STU  BOEUIFQSPDFTTUSBOTJUJPOTUPWX UPXBJUGPS*1WOBNFSFTPMVUJPO (hostname_resolution_waiting, nil, nil, remaining) %FUFSNJOFUIFOFYUTUBUFBTWX "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM 3FUSJFWF*1WBEESFTTPOMZ

Slide 69

Slide 69 text

case state when :v4w ipv6_resolved, _, = IO.select( if ipv6_resolved family_name, res = hostname_resolution_queue.get # ... state = :v46c else state = :v4c end next *OWX *0TFMFDUJTDBMMFEUPXBJUGPS*1WOBNF SFTPMVUJPO FWFOUIPVHI*1WIBTBMSFBEZCFFOSFTPMWFE   "OVOOFDFTTBSZ*0TFMFDUDBMMJTPDDVSSJOH &WFOUIPVHI*1WIBTBMSFBEZCFFOJOUIFRVFVF (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) "OFYBNQMFTPGUIFFYDFTTJWFMZBTUBUFUSBOTJUJPOMJLFJNQM 8BJUGPSNTGPS*1WOBNFSFTPMVUJPO *1W 3FUSJFWF*1WBEESFTT 5IFRVFVF

Slide 70

Slide 70 text

8IBU`TUIFQSPCMFN 1SFNJTF ɾ5IFDVSSFOUTUBUFJTNBOBHFEEVSJOHFYFDVUJPO ɾ&BDITUBUFIBTQSFEF fi OFEBDUJPOTBOE ɹDPOEJUJPOTGPSUSBOTJUJPOJOHUPUIFOFYUTUBUF

Slide 71

Slide 71 text

8IBU`TUIFQSPCMFN &WFOJGDPOEJUJPO"GPSUSBOTJUJPOJOHUPTUBUF"BOE DPOEJUJPO#GPSUSBOTJUJPOJOHUPTUBUF#BSFVOJOUFOUJPOBMMZTBUJT fi FE BUUIFTBNFUJNF # " TUBSU TBUJT fi FE TBUJT fi FE

Slide 72

Slide 72 text

8IBU`TUIFQSPCMFN &WFOJGDPOEJUJPO"GPSUSBOTJUJPOJOHUPTUBUF"BOE DPOEJUJPO#GPSUSBOTJUJPOJOHUPTUBUF#BSFVOJOUFOUJPOBMMZTBUJT fi FE BUUIFTBNFUJNF  POMZPOFPGUIFUXPŠFJUIFSTUBUF"PSTUBUF#ŠXJMMCFTFMFDUFE BTUIFOFYUTUBUF " TUBSU TBUJT fi FEBOETFMFDUFE TBUJT fi FEBOEOPUTFMFDUFE #

Slide 73

Slide 73 text

8IBU`TUIFQSPCMFN "TBSFTVMU  UIFSFJTBSJTLUIBUQSPDFTTJOHXIJDITIPVMEOPUIBWFCFFO QFSGPSNFEXJMMCFFYFDVUFEJOUIFTFMFDUFETUBUF  BOEQSPDFTTJOHXIJDITIPVMEIBWFCFFOQFSGPSNFEXJMMCFTLJQQFEJO UIFVOTFMFDUFETUBUF " TUBSU TBUJT fi FEBOETFMFDUFE &YFDVUFXIBUTIPVMEOPUEP $BOUFYFDVUFXIBUTIPVMEEP TBUJT fi FEBOEOPUTFMFDUFE #

Slide 74

Slide 74 text

5IJTJTTVFDBOCFBWPJEFECZJOUSPEVDJOHBOFXTUBUF$UIBU SFQSFTFOUTUIFDBTFXIFSFCPUIDPOEJUJPO"BOE#BSFTBUJT fi FE 5IBUJT JGXFBSFXJMMJOHUPBDDFQUUIFJODSFBTFEDPNQMFYJUZJOCPUI UIFTQFDJ fi DBUJPOBOEUIFJNQMFNFOUBUJPOUIBUDPNFTXJUI NBOBHJOHNPSFTUBUFT 8IBU`TUIFQSPCMFN " TUBSU $ # TBUJT fi FEBOETFMFDUFE

Slide 75

Slide 75 text

5IJTJTTVFDBOCFBWPJEFECZJOUSPEVDJOHBOFXTUBUF$UIBU SFQSFTFOUTUIFDBTFXIFSFCPUIDPOEJUJPO"BOE#BSFTBUJT fi FE 5IBUJT JGXFBSFXJMMJOHUPBDDFQUUIFJODSFBTFEDPNQMFYJUZJOCPUI UIFTQFDJ fi DBUJPOBOEUIFJNQMFNFOUBUJPOUIBUDPNFTXJUI NBOBHJOHNPSFTUBUFT 8IBU`TUIFQSPCMFN " TUBSU $ # "the excessively a state-transition-like impl"

Slide 76

Slide 76 text

#FGPSFXPSLJOHPO5$14PDLFUOFX -FUTSFJNQMFNFOU4PDLFUUDQ

Slide 77

Slide 77 text

$PODFQUPGUIFUIFJNQSPWFEWFSTJPOPG4PDLFUUDQ ɾ&MJNJOBUFDVSSFOUTUBUFNBOBHFNFOU ɾ&YFDVUFBMMQSPDFTTJOHUIBUDBOCFQFSGPSNFE ɹBUUIBUNPNFOU JOTUFBEPGFYFDVUJOHPOMZUIFQSPDFTTJOH ɹQSFEF fi OFEGPSFBDITUBUF 5IFJNQSPWFEWFSTJPOPG4PDLFUUDQ

Slide 78

Slide 78 text

5IFPWFSWJFXPGUIFJNQSPWFEWFSTJPOPG4PDLFUUDQ def self.tcp(host, port, ...) loop do if then timeout = IO.select(, , nil, ) if then if then if then end end -FUTSFWJFXUIFDIBOHFT

Slide 79

Slide 79 text

def self.tcp(host, port, ...) loop do # Processes in this loop end end 5IFPWFSWJFXPGUIFJNQSPWFEWFSTJPOPG4PDLFUUDQ 'JSTU UIFJOJUJBMJ[BUJPOPGWBSJBCMFTGPSNBOBHJOH UJNFPVUT TVDIBT3FTPMVUJPO%FMBZBOE $POOFDUJPO"UUFNQU%FMBZ BSFOFXMZBEEFE "EEFE

Slide 80

Slide 80 text

*OJUJBMJ[BUJPOPGUIFUJNFPVUWBSJBCMFT def self.tcp(host, port, ...) # Other initialization processes resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil loop do # Processes in this loop end end SFTPMVUJPO@EFMBZ@FYQJSFT@BUJTBWBSJBCMFUIBUTUPSFT UIFEFBEMJOFGPSXBJUJOHPO*1WOBNFSFTPMVUJPO BTQBSUPGUIF3FTPMVUJPO%FMBZ *OJUJBMJ[BUJPOPGUIFUJNFPVUWBSJBCMFT

Slide 81

Slide 81 text

*OJUJBMJ[BUJPOPGUIFUJNFPVUWBSJBCMFT def self.tcp(host, port, ...) # Other initialization processes resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil loop do # Processes in this loop end end DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUJTBWBSJBCMF UIBUTUPSFTUIFUJNFBUXIJDIUIFOFYUDPOOFDUJPO BUUFNQUDBOCFHJOBGUFSUIFQSFWJPVTPOFIBTTUBSUFE  BTQBSUPG$POOFDUJPO"UUFNQU%FMBZ *OJUJBMJ[BUJPOPGUIFUJNFPVUWBSJBCMFT

Slide 82

Slide 82 text

*OJUJBMJ[BUJPOPGUIFUJNFPVUWBSJBCMFT def self.tcp(host, port, ...) # Other initialization processes resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil loop do # Processes in this loop end end 5IFTFWBSJBCMFTBSFJOJUJBMMZTFUUPOJM 5IFWBMVFTXJMMCFTFUMBUFS XIFOXBJUJOHCFDPNFT OFDFTTBSZ *OJUJBMJ[FXJUIOJM

Slide 83

Slide 83 text

def self.tcp(host, port, ...) # Other initialization processes resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil loop do # Processes in this loop end end 4UBSUIPTUOBNFSFTPMVUJPOJODIJMEUISFBET /FYU UIFNFUIPEGPSOBNFSFTPMVUJPOJTDBMMFE 5IFJNQMFNFOUBUJPOBOEJOWPDBUJPOPGUIJTNFUIPEBSF NPTUMZUIFTBNFBTQSFWJPVTJNQMFNFOUBUJPO &YFDVUFUIFOBNFSFTPMVUJPONFUIPE

Slide 84

Slide 84 text

def self.tcp(host, port, ...) # Other initialization processes resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil loop do # Processes in this loop end end 4UBSUBMPPQ 4UBSUBMPPQ

Slide 88

Slide 88 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at # ... end 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 89

Slide 89 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at # ... end 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO "UMFBTUPOFBEESFTTGBNJMZIBTDPNQMFUFEOBNF SFTPMVUJPO BOEUIFSFBSFBWBJMBCMFDBOEJEBUF BEESFTTFTUPDPOOFDUUP 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 90

Slide 90 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at # ... end SFTPMVUJPO@EFMBZ@FYQJSFT@BUJTOJM  NFBOJOHJUJTOPUEVSJOH3FTPMVUJPO%FMBZ 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 91

Slide 91 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at # ... end DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUJTOJM  NFBOJOHJUJTOPUEVSJOH$POOFDUJPO"UUFNQU%FMBZ 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 92

Slide 92 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at while (addrinfo = resolution_store.get_addrinfo) # ... socket = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) socket.bind(local_addrinfo) if local_addrinfo result = socket.connect_nonblock(addrinfo, exception: false) if result == :wait_writable # ... # ... connecting_sockets[socket] = addrinfo # ... end end end *GBMMUIFTFDPOEJUJPOTBSFNFU  POFEFTUJOBUJPOBEESFTTJT3FUSJFWF  BOETUBSUBDPOOFDUJPOBUUFNQUJOOPOCMPDLJOHNPEF 3FUSJFWFBOBEESFTT 4UBSUBOPOCMPDLJOHDPOOFDU 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 93

Slide 93 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at while (addrinfo = resolution_store.get_addrinfo) # ... socket = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) socket.bind(local_addrinfo) if local_addrinfo result = socket.connect_nonblock(addrinfo, exception: false) if result == :wait_writable connection_attempt_delay_expires_at = now + CONNECTION_ATTEMPT_DELAY # ... end end end DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUJTTFUUP UIFDVSSFOUUJNF NT5IJTSFQSFTFOUTUIFUJNFBU XIJDIUIFOFYUDPOOFDUJPOBUUFNQUDBOCFHJO 5IFDVSSFOUUJNF NT 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 94

Slide 94 text

if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at while (addrinfo = resolution_store.get_addrinfo) # ... socket = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) socket.bind(local_addrinfo) if local_addrinfo result = socket.connect_nonblock(addrinfo, exception: false) if result == :wait_writable connection_attempt_delay_expires_at = now + CONNECTION_ATTEMPT_DELAY # ... connecting_sockets[socket] = addrinfo # ... end end end 5IFOTUPSFUIFTPDLFUVTFEGPSUIFDPOOFDUJPOBUUFNQU  FYJUUIJTJGTUBUFNFOU 4UPSFUIFTPDLFU 5IFDPOEJUJPOUPTUBSUBDPOOFDUJPO

Slide 95

Slide 95 text

loop do if then timeout = IO.select(, , nil, ) if then if then if then end "GUFSUIF fi STUDPOEJUJPO 5IFOFYUTUFQJTUPDBMM*0TFMFDU

Slide 99

Slide 99 text

$BMDVMBUFUIFUJNFPVUWBMVF ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end )FSFJUJT

Slide 100

Slide 100 text

ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end *GUIFSFBSFDBOEJEBUFBEESFTTFTBWBJMBCMFBUUIJTQPJOU $BMDVMBUFUIFUJNFPVUWBMVF

Slide 101

Slide 101 text

ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end BOE3FTPMVUJPO%FMBZJTJOQSPHSFTT  SFTPMVUJPO@EFMBZ@FYQJSFT@BUXJMMIBWFBWBMVF  BOEUIBUWBMVFJTSFUVSOFE $BMDVMBUFUIFUJNFPVUWBMVF

Slide 102

Slide 102 text

$BMDVMBUFUIFUJNFPVUWBMVF ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end *G3FTPMVUJPO%FMBZJTOPUJOQSPHSFTT UIFWBMVFTFU DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUJTSFUVSOFE JOTUFBE

Slide 103

Slide 103 text

$BMDVMBUFUIFUJNFPVUWBMVF ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end *GUIFSFBSFOPBWBJMBCMFDBOEJEBUFBEESFTTFT  5IJTNFBOTFJUIFSOPOBNFSFTPMVUJPOIBTCFFO DPNQMFUFEZFU PSDPOOFDUJPOBUUFNQUTIBWFBMSFBEZ CFFOTUBSUFEGPSBMMSFTPMWFEBEESFTTFTBUUIJTQPJOU

Slide 104

Slide 104 text

$BMDVMBUFUIFUJNFPVUWBMVF ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end *OUIJTDBTF JGTPNFVTFSTQFDJ fi FEUJNFPVUWBMVFT BSFQSPWJEFEBTBOBSHVNFOUUP4PDLFUUDQ  UIFMBSHFSWBMVFJTVTFE

Slide 105

Slide 105 text

ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end *GOPVTFSTQFDJ fi FEUJNFPVUJTHJWFO  BXPSLBSPVOEJTBQQMJFEUPSFUVSOBWBMVFUIBU F ff FDUJWFMZXBJUTJOEF fi OJUFMZ EFUBJMTPNJUUFEIFSF  $BMDVMBUFUIFUJNFPVUWBMVF

Slide 106

Slide 106 text

ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, is_windows_environment ? connecting_sockets.keys : nil, second_to_timeout(current_clock_time, ends_at), ) $BMM*0TFMFDUXJUIUIFUJNFPVUWBMVFDBMDVMBUFEGSPN UIFSFUVSOWBMVFPGUIJTMPHJD $BMM*0TFMFDUXJUIUIFUJNFPVUWBMVF "DUVBMUJNFPVUWBMVF

Slide 107

Slide 107 text

ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max end hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, is_windows_environment ? connecting_sockets.keys : nil, second_to_timeout(current_clock_time, ends_at), ) "TWXJOUIFQSFWJPVTJNQMFNFOUBUJPO  UIFBSHVNFOUTPUIFSUIBOUIFUJNFPVUBSF ɾ5IFQJQFXBJUJOHGPSOBNFSFTPMVUJPOOPUJ fi DBUJPOT ɾ5IFTPDLFUTDVSSFOUMZBUUFNQUJOHUPDPOOFDU $BMM*0TFMFDUXJUIUIFUJNFPVUWBMVF 5IFQJQFXBJUJOHGPSOBNFSFTPMVUJPOOPUJ fi DBUJPO 5IFTPDLFUTBUUFNQUJOHUPDPOOFDU

Slide 108

Slide 108 text

"GUFS*0TFMFDU hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, is_windows_environment ? connecting_sockets.keys : nil, second_to_timeout(current_clock_time, ends_at), ) now = current_clock_time if expired?(now, resolution_delay_expires_at) resolution_delay_expires_at = nil end if expired?(now, connection_attempt_delay_expires_at) connection_attempt_delay_expires_at = nil end 0ODF*0TFMFDUVOCMPDLT UIF fi STUTUFQJTUP DIFDLUIFWBMVFTPGUIFUJNFPVUWBSJBCMFT SFTPMVUJPO@EFMBZ@FYQJSFT@BUJTQBTU  DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUJTQBTU 

Slide 109

Slide 109 text

hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, is_windows_environment ? connecting_sockets.keys : nil, second_to_timeout(current_clock_time, ends_at), ) now = current_clock_time if expired?(now, resolution_delay_expires_at) resolution_delay_expires_at = nil end if expired?(now, connection_attempt_delay_expires_at) connection_attempt_delay_expires_at = nil end 3FTFU "GUFS*0TFMFDU *GBOZTUPSFEUJNFIBTBMSFBEZQBTTFEBUUIJTQPJOU  JUJTSFTFUUPOJM 3FTFU

Slide 111

Slide 111 text

0OFPSNPSFXSJUBCMFTPDLFUTBSFBWBJMBCMF if writable_sockets&.any? while (writable_socket = writable_sockets.pop) is_connected = is_windows_environment || ( sockopt = writable_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) sockopt.int.zero? ) if is_connected connecting_sockets.delete writable_socket return writable_socket else # ... end end end *GUIFSFBSFXSJUBCMFTPDLFUT DIFDLUIFJSDPOOFDUJPO TUBUVT*GUIFDPOOFDUJPOJTTVDDFTTGVM  SFUVSOUIFTPDLFUBOEFYJU4PDLFUUDQ *TUIFDPOOFDUJPOTVDDFTTGVM  3FUVSOUIFTVDDFTTGVMMZDPOOFDUFETPDLFU $IFDLUIFDPOOFDUJPOTUBUVT

Slide 112

Slide 112 text

if hostname_resolved&.any? while (family_and_result = hostname_resolution_result.get) family_name, result = family_and_result if result.is_a? Exception # ... else resolution_store.add_resolved(family_name, result) end end # ... end *GBOBNFSFTPMVUJPOOPUJ fi DBUJPOIBTBSSJWFEPO UIFQJQF SFUSJFWFUIFSFTPMWFEBEESFTTFT BOETUPSFUIFN "OBNFSFTPMVUJPOOPUJ fi DBUJPOIBTBSSJWFE 0CUBJOSFTPMWFEBEESFTTFT 4UPSFUIFPCUBJOFEBEESFTTFT

Slide 113

Slide 113 text

if hostname_resolved&.any? while (family_and_result = hostname_resolution_result.get) # ... end if resolution_store.resolved?(:ipv4) if resolution_store.resolved?(:ipv6) hostname_resolution_notifier = nil resolution_delay_expires_at = nil user_specified_resolv_timeout_at = nil elsif resolution_store.resolved_successfully?(:ipv4) resolution_delay_expires_at = now + RESOLUTION_DELAY end end end *GPOMZ*1WJTSFTPMWFEBOE*1WJTTUJMMVOSFTPMWFE TFU SFTPMVUJPO@EFMBZ@FYQJSFT@BUUPUIFDVSSFOUUJNF  NTUPXBJUGPS*1WSFTPMVUJPOJOUIFOFYUMPPQ "OBNFSFTPMVUJPOOPUJ fi DBUJPOIBTBSSJWFE 4FUSFTPMVUJPO@EFMBZ@FYQJSFT@BU *1WIBTCFFOSFTPMWFE *1WIBTOPUCFFOSFTPMWFE

Slide 115

Slide 115 text

loop do # ... if resolution_store.empty_addrinfos? if connecting_sockets.empty? && resolution_store.resolved_all_families? raise last_error end if (expired?(now, user_specified_resolv_timeout_at) || ...) && (expired?(now, user_specified_connect_timeout_at) || ...) raise Errno::ETIMEDOUT, 'user specified timeout' end end end ɾ*GUIFSFBSFOPBWBJMBCMFBEESFTTDBOEJEBUFT ɾ"OEUIFSFBSFOPTPDLFUTDVSSFOUMZDPOOFDUJOH ɾ"OEBMMOBNFSFTPMVUJPOTIBWFDPNQMFUFE UIFOOPGVSUIFSQSPDFTTJOHDBOCFQFSGPSNFE  TPBOFYDFQUJPOJTSBJTFE 8IFUIFSUIFOFYUMPPQJUFSBUJPODBOQSPDFFE 3BJTFBOFYDFQUJPO

Slide 116

Slide 116 text

loop do # ... if resolution_store.empty_addrinfos? if connecting_sockets.empty? && resolution_store.resolved_all_families? raise last_error end if (expired?(now, user_specified_resolv_timeout_at) || ...) && (expired?(now, user_specified_connect_timeout_at) || ...) raise Errno::ETIMEDOUT, 'user specified timeout' end end end *GUIFVTFSTQFDJ fi FEUJNFPVUTIBWFCFFOFYDFFEFE  SBJTFBUJNFPVUFYDFQUJPO 8IFUIFSUIFOFYUMPPQJUFSBUJPODBOQSPDFFE 3BJTFBUJNFPVUFYDFQUJPO

Slide 117

Slide 117 text

loop do # ... if resolution_store.empty_addrinfos? if connecting_sockets.empty? && resolution_store.resolved_all_families? raise last_error end if (expired?(now, user_specified_resolv_timeout_at) || ...) && (expired?(now, user_specified_connect_timeout_at) || ...) raise Errno::ETIMEDOUT, 'user specified timeout' end end end 0UIFSXJTF TJODFUIFSFBSFTUJMMFYFDVUBCMFQSPDFTTFT SFNBJOJOH QSPDFFEUPUIFOFYUMPPQJUFSBUJPO 8IFUIFSUIFOFYUMPPQJUFSBUJPODBOQSPDFFE 5PCFDPOUJOVFE ⬇︎

Slide 118

Slide 118 text

Slide 119

Slide 119 text

def self.tcp(host, port, ...) loop do if then timeout = IO.select(, , nil, ) if then if then if then end end 5IFJNQSPWFEWFSTJPOPG4PDLFUUDQ 5IFJNQSPWFEWFSTJPOPG4PDLFUUDQJTOPXDPNQMFUF

Slide 120

Slide 120 text

+VMZ 

Slide 121

Slide 121 text

+VMZ  5IJTWFSTJPOPG4PDLFUUDQJTNFSHFE JOUP3VCZNBTUFS IUUQTHJUIVCDPNSVCZSVCZQVMM .FSHFE

Slide 122

Slide 122 text

8JUIUIJT4PDLFUUDQJNQMFNFOUBUJPO BTUIFGPVOEBUJPO  JUT fi OBMMZSFBEZUPTUBSUXPSLJOHPO 5$14PDLFUOFX

Slide 123

Slide 123 text

%FDFNCFS  5JNFHPFTCBDLUP

Slide 124

Slide 124 text

%FDFNCFS  5JNFHPFTCBDLUP 4UBSUFEUPUIJOLPG5$14PDLFUOFX

Slide 125

Slide 125 text

IUUQTYDPNUPNPHTUBUVT .F !BLS !OBSTF %FDFNCFS 

Slide 126

Slide 126 text

5IJOLPG5$14PDLFUOFX 5$14PDLFUOFX MJLF4PDLFUUDQ  JTBNFUIPEUIBUSFUVSOTBDMJFOUTPDLFUDPOOFDUFEUPB TFSWFSWJB5$1  5IFEJ ff FSFODFTGSPN4PDLFUUDQBSF ɾ*UEPFTOPUBDDFQUBCMPDLBSHVNFOU ɾ*UJTJNQMFNFOUFEJOUFSOBMMZJO$

Slide 127

Slide 127 text

*OPSEFSUPTVQQPSU)&WJO5$14PDLFUOFX  BMBSHFQPSUJPOPGUIF4PDLFUUDQDPEFOFFETUPCF SFJNQMFNFOUFEJO$ 5IJOLPG5$14PDLFUOFX

Slide 128

Slide 128 text

5IJOLPG5$14PDLFUOFX *OPSEFSUPTVQQPSU)&WJO5$14PDLFUOFX  BMBSHFQPSUJPOPGUIF4PDLFUUDQDPEFOFFETUPCF SFJNQMFNFOUFEJO$ 0OFPGUIFLFZDIBMMFOHFTJTUIBUUIFTPDLFUMJCSBSZ IBEOPJOUFSOBMGVODUJPOGPSXBJUJOHPOOBNFSFTPMVUJPO VTJOHQJQFBOETFMFDU  

Slide 129

Slide 129 text

$IBMMFOHFTTQFDJ fi DUP5$14PDLFUOFX 1SFSFRVJTJUF 5IF3VCZTPDLFUMJCSBSZQSPWJEFTNFUIPETGPSOBNFSFTPMVUJPO  TVDIBT"EESJOGPHFUBEESJOGPBOE4PDLFUHFUBEESJOGP 'PSFYBNQMF "EESJOGPHFUBEESJOGPJTVTFEJO4PDLFUUDQXJUI )&W begin resolved_addrinfos = Addrinfo.getaddrinfo(...) hostname_resolution_queue.add_resolved(...) rescue => e # ... end

Slide 130

Slide 130 text

1SFSFRVJTJUF 6OUJM3VCZ UIFTFNFUIPETIBEBMJNJUBUJPO UIFZDPVMEO`UCFJOUFSSVQUFEPODFFYFDVUJPOIBETUBSUFE 5IJTXBTCFDBVTFUIFZJOUFSOBMMZSFMJFEPOUIF$MJCSBSZ GVODUJPOHFUBEESJOGP  XIJDIJTBCMPDLJOHGVODUJPO ŠUIBUJT PODFDBMMFE JUDBOOPUCFJOUFSSVQUFEVOUJMOBNF SFTPMVUJPODPNQMFUFT $IBMMFOHFTTQFDJ fi DUP5$14PDLFUOFX

Slide 131

Slide 131 text

1SFSFRVJTJUF 4UBSUJOHGSPN3VCZ UIJTIBTCFFOJNQSPWFE POFOWJSPONFOUTXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF  OBNFSFTPMVUJPODBOOPXCFJOUFSSVQUFEFWFOXIJMFJOQSPHSFTT 3FG.BLFUIFOBNFSFTPMVUJPOJOUFSSVQUJCMF IUUQTHJUIVCDPNSVCZSVCZQVMM $IBMMFOHFTTQFDJ fi DUP5$14PDLFUOFX

Slide 132

Slide 132 text

*OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ FH5IFDBMMTUBDLPG"EESJOGPHFUBEESJOGP "EESJOGPHFUBEESJOGP  ➡︎ BEESJOGP@T@HFUBEESJOGP ɹ ➡︎ BEESJOGP@MJTU@OFX ɹ ➡︎ DBMM@HFUBEESJOGP ɹɹ ➡︎ STPDL@HFUBEESJOGP ɹɹ ➡︎ SC@HFUBEESJOGP -FUTTFFIPXUIFTFNFUIPETNBLFUIF OBNFSFTPMVUJPOJOUFSSVQUJCMFJO3VCZ *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF

Slide 133

Slide 133 text

FH5IFDBMMTUBDLPG"EESJOGPHFUBEESJOGP "EESJOGPHFUBEESJOGP  ➡︎ BEESJOGP@T@HFUBEESJOGP ɹ ➡︎ BEESJOGP@MJTU@OFX ɹ ➡︎ DBMM@HFUBEESJOGP ɹɹ ➡︎ STPDL@HFUBEESJOGP ɹɹ ➡︎ SC@HFUBEESJOGP *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ Attention! *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF

Slide 134

Slide 134 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD BOEEFUBDIJU 4QBXOBOFXDIJMEUISFBE *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF *OTJEFSC@HFUBEESJOGP  BOFXDIJMEUISFBEJTTQBXOFEBOEEFUBDIFE GSPNUIFNBJOUISFBE

Slide 135

Slide 135 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ static void *do_getaddrinfo(void *ptr) { // ... int err, gai_errno; err = getaddrinfo(...); // ... } $BMMHFUBEESJOGP   IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF *OUIFEFUBDIFEDIJMEUISFBE HFUBEESJOGP  JTDBMMFE

Slide 136

Slide 136 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ static void *do_getaddrinfo(void *ptr) { // ... arg->done = 1; rb_native_cond_signal(&arg->cond); // ... } 4JHOBMUPUIFNBJOUISFBE IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF 0ODFOBNFSFTPMVUJPOXJUIHFUBEESJOGP  JTDPNQMFUF  OPUJGZJUUPUIFNBJOUISFBEVTJOHBDPOEJUJPOWBSJBCMF

Slide 137

Slide 137 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF *OUIFNBJOUISFBE JUXBJUTVOUJMBOPUJ fi DBUJPOBSSJWFT POUIFDPOEJUJPOWBSJBCMF 8BJUGPSOPUJ fi DBUJPOUPUIFDPOEJUJPOWBSJBCMF

Slide 138

Slide 138 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF %FUFDUTBDPNQMFUJPOPGOBNFSFTPMVUJPO %FUFDUTBOJOUFSSVQUJPO 5IJTDPOEJUJPOWBSJBCMFJTOPUJ fi FEOPUPOMZ XIFOOBNFSFTPMVUJPODPNQMFUFTJOBDIJMEUISFBE  CVUBMTPXIFOUIFNFUIPEJTJOUFSSVQUFE

Slide 139

Slide 139 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF 5PCFDPOUJOVFE ⬇︎ 0ODFUIFOPUJ fi DBUJPOBSSJWFT UIFXBJUJTMJGUFE  BOEUIFTVCTFRVFOUQSPDFTTJOHJTDBSSJFEPVU CBTFEPOUIFSFBTPOUIBUUSJHHFSFEUIFOPUJ fi DBUJPO

Slide 140

Slide 140 text

static int rb_getaddrinfo(...) { // ... pthread_t th; if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } pthread_detach(th); rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); // ... } *OUFSSVQUJCMFHFUBEESJOGP*NQMFNFOUBUJPO BTPG3VCZ IUUQTHJUIVCDPNSVCZSVCZCMPCSVCZ@@FYUTPDLFUSBEESJOGPD *OBOFOWJSPONFOUXIFSFUIFQUISFBEMJCSBSZJTBWBJMBCMF 5PCFDPOUJOVFE ⬇︎ 8JUIUIBUJONJOE MFUTHFUCBDLUPUIFNBJOUPQJD

Slide 141

Slide 141 text

5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@JOFUTPDL@JOUFSOBM  ➡︎ STPDL@BEESJOGPɹ  ➡︎ STPDL@HFUBEESJOGP  ➡︎ SC@HFUBEESJOGP  ➡︎  5IFDBMMTUBDLPG5$14PDLFUOFX 3VCZ *OUFSSVQUJCMFOBNFSFTPMVUJPO *O5$14PDLFUOFX  SC@BEESJOGPJTBMTPVTFEGPSOBNFSFTPMVUJPO 4UBSUOBNFSFTPMVUJPO

Slide 142

Slide 142 text

5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@JOFUTPDL@JOUFSOBM  ➡︎ STPDL@BEESJOGPɹ  ➡︎ STPDL@HFUBEESJOGP  ➡︎ SC@HFUBEESJOGP  ➡︎  5IFDBMMTUBDLPG5$14PDLFUOFX 3VCZ 5IFQSPCMFNJTUIBUSC@HFUBEESJOGPJTOPUEFTJHOFE GPS)&W Not for HEv2 ...

Slide 143

Slide 143 text

4QFDJ fi DBUJPO%J ff FSFODF 5IFOVNCFSPGDIJMEUISFBETTQBXOFE SC@HFUBEESJOGP $SFBUFDIJMEUISFBE 'VODUJPOGPS5$14PDLFUOFX $SFBUFrDIJMEUISFBET POFGPSFBDIBEESFTTGBNJMZ SC@HFUBEESJOGPWT5$14PDLFUOFXXJUI)&W SC@HFUBEESJOGP 4QBXODIJMEUISFBE  EPFTOPUTQFDJGZ BOBEESFTTGBNJMZEVSJOH OBNFSFTPMVUJPO 5$14PDLFUOFXGPS)&W 4QBXOrDIJMEUISFBET  POFGPSFBDIBEESFTTGBNJMZ

Slide 144

Slide 144 text

4QFDJ fi DBUJPO%J ff FSFODF %FUFDUJOHOBNFSFTPMVUJPODPNQMFUJPO 5$14PDLFUOFXGPS)&W 6TJOHBQJQFBOETFMFDU   #FDBVTFJUOFFETUPXBJUOPU POMZGPSOBNFSFTPMVUJPOCVU BMTPGPSTPDLFUTBUUFNQUJOH UPDPOOFDU SC@HFUBEESJOGP 6TJOHBDPOEJUJPOWBSJBCMF SC@HFUBEESJOGPWT5$14PDLFUOFXXJUI)&W

Slide 145

Slide 145 text

4QFDJ fi DBUJPO%J ff FSFODF .FUIPETUIBUDBMMUIJTGVODUJPO SC@HFUBEESJOGP 6TFECZNVMUJQMFNFUIPETUIBUOFFEOBNFSFTPMVUJPO FH"EESJOGPHFUBEESJOGP 4PDLFUHFUBEESJOGP *14PDLFUHFUBEESFTT  SC@HFUBEESJOGPWT5$14PDLFUOFXXJUI)&W

Slide 146

Slide 146 text

5$14PDLFUOFXXJUI)&WOFFET BOFXNFDIBOJTNTQFDJ fi DBMMZEFTJHOFEGPS 5$14PDLFUOFXJUTFMG

Slide 147

Slide 147 text

<#FGPSF>5IF5$14PDLFUOFXJNQMFNFOUBUJPO 5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@JOFUTPDL@JOUFSOBM  ➡︎ STPDL@BEESJOGPɹ  ➡︎ STPDL@HFUBEESJOGP  ➡︎ SC@HFUBEESJOGP  ➡︎  )FSFJTUIFDBMMTUBDLPG5$14PDLFUOFX CFGPSFUIFDIBOHF

Slide 148

Slide 148 text

5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@GBTU@GBMMCBDL@JOFUTPDL@JOUFSOBM  ➡︎ SBEESJOGP@QUISFBE@DSFBUF  ➡︎ EP@GBTU@GBMMCBDL@HFUBEESJOGPɹ  ➡︎ SC@UISFBE@DBMM@XJUIPVU@HWM  ➡︎ XBJU@GBTU@GBMMCBDLDBODFM@GBTU@GBMMCBDL  ➡︎  "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM )FSFJTUIFDBMMTUBDLPG5$14PDLFUOFX BGUFSUIFDIBOHF <"GUFS>5IF5$14PDLFUOFXJNQMFNFOUBUJPO

Slide 149

Slide 149 text

5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@GBTU@GBMMCBDL@JOFUTPDL@JOUFSOBM  ➡︎ SBEESJOGP@QUISFBE@DSFBUF  ➡︎ EP@GBTU@GBMMCBDL@HFUBEESJOGPɹ  ➡︎ SC@UISFBE@DBMM@XJUIPVU@HWM  ➡︎ XBJU@GBTU@GBMMCBDLDBODFM@GBTU@GBMMCBDL  ➡︎  <"GUFS>5IF5$14PDLFUOFXJNQMFNFOUBUJPO "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM Attention!

Slide 150

Slide 150 text

*OUIFNBJOUISFBE static VALUE init_fast_fallback_inetsock_internal(VALUE v) { // ... if (raddrinfo_pthread_create(..., do_fast_fallback_getaddrinfo, ...) != 0) { rsock_raise_resolution_error("getaddrinfo(3)", EAI_AGAIN); } pthread_detach(threads[i]); // ... } *OTJEFJOJU@GBTU@GBMMCBDL@JOFUTPDL@JOUFSOBM  BOFXUISFBEJTDSFBUFEBOEEFUBDIFE GPSFBDIBEESFTTGBNJMZ "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM BOEEFUBDIJU $SFBUFBOFXUISFBE

Slide 151

Slide 151 text

*OUIFNBJOUISFBE static VALUE init_fast_fallback_inetsock_internal(VALUE v) { // ... if (raddrinfo_pthread_create(..., do_fast_fallback_getaddrinfo, ...) != 0) { // ... } pthread_detach(threads[i]); // ... } *OTJEFFBDIPGUIFEFUBDIFEDIJMEUISFBET HFUBEESJOGP  JTDBMMFE $BMMJOUIFUISFBE "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM void *do_fast_fallback_getaddrinfo(void *ptr) { // ... int err, gai_errno; err = getaddrinfo(...); // ... } $BMMHFUBEESJOGP  

Slide 152

Slide 152 text

*OUIFNBJOUISFBE static VALUE init_fast_fallback_inetsock_internal(VALUE v) { // ... if (raddrinfo_pthread_create(..., do_fast_fallback_getaddrinfo, ...) != 0) { // ... } pthread_detach(threads[i]); // ... } 0ODFOBNFSFTPMVUJPOJTDPNQMFUF  BOPUJ fi DBUJPOJTTFOUUPUIFQJQFTIBSFEXJUI UIFNBJOUISFBE $BMMJOUIFUISFBE "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM void *do_fast_fallback_getaddrinfo(void *ptr) { // ... write(shared->notify, ¬ification, strlen(¬ification)); // ... } 8SJUFUIFOPUJGZUPUIFQJQF

Slide 153

Slide 153 text

*OUIFNBJOUISFBE static VALUE init_fast_fallback_inetsock_internal(VALUE v) { // ... if (raddrinfo_pthread_create(..., do_fast_fallback_getaddrinfo, ...) != 0) { rsock_raise_resolution_error("getaddrinfo(3)", EAI_AGAIN); } pthread_detach(threads[i]); // ... rb_thread_call_without_gvl2( wait_fast_fallback, &wait_arg, cancel_fast_fallback, arg->getaddrinfo_shared ); // ... } .FBOXIJMF JOUIFNBJOUISFBE DBMMBGVODUJPOUPXBJU GPSCPUIOBNFSFTPMVUJPOPSBDPOOFDUJPOUPDPNQMFUF 8BJUGPSCPUIDPOOFDUJPODPNQMFUJPO BOEOBNFSFTPMVUJPO 5PCFDPOUJOVFE ⬇︎ "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 154

Slide 154 text

8BJUJOHGPSCPUIDPOOFDUJPOBOEOBNFSFTPMVUJPO static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } *OUIFXBJUJOHGVODUJPO DBMMTFMFDU  UPNPOJUPSCPUI UIFQJQFXBJUJOHGPSOBNFSFTPMVUJPOOPUJ fi DBUJPOBOE UIFTPDLFUTDVSSFOUMZBUUFNQUJOHUPDPOOFDU "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 155

Slide 155 text

static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } TFMFDU  VOCMPDLTXIFOFJUIFSBOBNFSFTPMVUJPO DPNQMFUJPOOPUJ fi DBUJPOBSSJWFTPOUIFQJQF BOZPGUIF TPDLFUTDVSSFOUMZBUUFNQUJOHUPDPOOFDUCFDPNF XSJUBCMF PSUIFXBJUUJNFFYDFFETUIFUJNFPVU "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 8BJUJOHGPSCPUIDPOOFDUJPOBOEOBNFSFTPMVUJPO *ODMVEFTUIFQJQF *ODMVEFTUIFTPDLFUTBUUFNQUJOHUPDPOOFDU

Slide 156

Slide 156 text

static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } *OTIPSU UIJTTFMFDU  QFSGPSNTUIFTBNFSPMFBTUIF *0TFMFDUJOUIF4PDLFUUDQJNQMFNFOUBUJPO "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 8BJUJOHGPSCPUIDPOOFDUJPOBOEOBNFSFTPMVUJPO

Slide 157

Slide 157 text

5$14PDLFUOFX  ➡︎ UDQ@JOJU  ➡︎ STPDL@JOJU@JOFUTPDL  ➡︎ JOJU@GBTU@GBMMCBDL@JOFUTPDL@JOUFSOBM  ➡︎ SBEESJOGP@QUISFBE@DSFBUF  ➡︎ EP@GBTU@GBMMCBDL@HFUBEESJOGPɹ  ➡︎ SC@UISFBE@DBMM@XJUIPVU@HWM  ➡︎ XBJU@GBTU@GBMMCBDLDBODFM@GBTU@GBMMCBDL  ➡︎  $BMM4UBDLPG5$14PDLFUOFXXJUI)&W "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM "OBNFSFTPMVUJPOGVODUJPO JOUIFDIJMEUISFBE 4QBXOBOFXDIJMEUISFBE 8BJUJOUIFNBJOUISFBE 5IJTJNQMFNFOUBUJPOBMTPSFRVJSFTUIFQUISFBEMJCSBSZ 5$14PDLFUOFXXJUI)&WJTPOMZJOFOWJSPONFOUT XIFSFQUISFBEJTBWBJMBCMFBOECFIBWFTBTJUBMXBZT IBTPOQMBUGPSNTMJLF8JOEPXT

Slide 158

Slide 158 text

%FWFMPQNFOUPO5$14PDLFUOFX IBECFFOQBVTFEBGUFS3VCZ,BJHJ XIJMF4PDLFUUDQXBTCFJOHSFJNQMFNFOUFEŠ

Slide 159

Slide 159 text

+VMZ  3FTVNFJNQMFNFOUBUJPOPG5$14PDLFUOFX "GUFSUIFTFDPOENFSHFPG4PDLFUUDQ

Slide 160

Slide 160 text

4FQUFNCFS 

Slide 161

Slide 161 text

4FQUFNCFS  0QFOB1VMM3FRVFTUGPS5$14PDLFUOFX IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 162

Slide 162 text

)PXFWFS  XIJMF*XBTNBLJOH fi YFTUPHFUUIF$*UPQBTT BOESFRVFTUJOHSFWJFXT

Slide 163

Slide 163 text

0DUPCFS 

Slide 164

Slide 164 text

0DUPCFS  3VCZQSFWJFXSFMFBTFE 5$14PDLFUOFXXJUI)&WEJEO`UNBLFJUJOUJNF

Slide 165

Slide 165 text

/PWFNCFS 

Slide 166

Slide 166 text

/PWFNCFS  !ITCUSFDPNNFOEFENFBTB3VCZDPNNJUUFS !NBU[ :VLJIJSP.BUTVNPUP *QSPQPTF!TIJPJNN .JTBLJ 4IJPJ BTB3VCZDPNNJUUFS4IFJTCFTUQFSTPOUPNBJOUBJO )&WBOE4PDLFUSFMBUFEGFBUVSF*UTHPPEUJNFUPDPNNJU IUUQTHJUIVCDPNSVCZSVCZQVMMCZIFSTFMG IUUQTCVHTSVCZMBOHPSHJTTVFT

Slide 167

Slide 167 text

/PWFNCFS 

Slide 168

Slide 168 text

/PWFNCFS  "DDFQUFE  .BU[ IUUQTCVHTSVCZMBOHPSHJTTVFT

Slide 169

Slide 169 text

/PWFNCFS 

Slide 170

Slide 170 text

/PWFNCFS  *CFDBNFBOFX3VCZDPNNJUUFS :PV`WFCFFOBEEFEUPUIFSVCZDPNNJUUFSTUFBN GPSUIFPSHBOJ[BUJPO 5IF3VCZ1SPHSBNNJOH-BOHVBHF

Slide 171

Slide 171 text

/PWFNCFS  "GUFS fi OJTIJOHUIF fi YFTCBTFEPOUIFSFWJFX

Slide 172

Slide 172 text

/PWFNCFS  .FSHFE13JOUPNBTUFS

Slide 173

Slide 173 text

15 of 29 CIs failed!! /PWFNCFS 

Slide 174

Slide 174 text

8IJDIUFTUTXFSFGBJMJOHPO$* 0SUFTUTTJNJMBSUPUIFTFBSFJODMVEFEJOUIFUFTUTGPS /FU)551 > 1) Failure: > TestNetHTTP_v1_2_chunked#test_timeout_during_HTTP_session_write > [/.../ruby/test/net/http/test_http.rb:572]: > [Net::WriteTimeout] exception expected, > not #.

Slide 175

Slide 175 text

5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 176

Slide 176 text

5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end *OUIJTUFTU BTFSWFSJT fi STUTUBSUFEPOMPDBMIPTU 4UBSUB5$1TFSWFS UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 177

Slide 177 text

5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end 5IFO UIFDMJFOUTUJNFPVUWBMVFTBSFTFU BXSJUFUJNFPVUPGNT BOEBDPOOFDUUJNFPVUPGNT XSJUFUJNFPVUNT DPOOFDUUJNFPVUNT UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 178

Slide 178 text

5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end 5IFDMJFOUUIFOTUBSUTBDPOOFDUJPOUPUIFTFSWFS 4UBSUBOFXDPOOFDUJPO UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 179

Slide 179 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end 5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF 4FOEBWFSZMPOHTUSJOH *GUIFDPOOFDUJPOJTTVDDFTTGVM  JUBUUFNQUTUPTFOEBWFSZMPOHTUSJOH BTBSFRVFTUNFTTBHFUPUIFTFSWFS UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 180

Slide 180 text

5FTU/FU)551@W@@DIVOLFEUFTU@UJNFPVU@EVSJOH@)551@TFTTJPO@XSJUF def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end 5IFFYQFDUBUJPOJTUIBUEVSJOHUIFTFOE NTXJMM QBTTBOE/FU8SJUF5JNFPVUBTBXSJUFUJNFPVU XJMMCFSBJTFE UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 181

Slide 181 text

/PU/FU8SJUF5JNFPVU CVU/FU0QFO5JNFPVU *OUIFGBJMJOHUFTU  /FU0QFO5JNFPVUPDDVSTXIFSF/FU8SJUF5JNFPVUJTFYQFDUFE 5IJTJOEJDBUFTUIBUUIFUJNFPVUJTIBQQFOJOHEVSJOHUIFDPOOFDUJPO BUUFNQU CFGPSFUIFXSJUFFWFOCFHJOT > 1) Failure: > TestNetHTTP_v1_2_chunked#test_timeout_during_HTTP_session_write > [/.../ruby/test/net/http/test_http.rb:572]: > [Net::WriteTimeout] exception expected, > not #.

Slide 182

Slide 182 text

/FU)551DPOOFDU def connect # ... s = Timeout.timeout(@open_timeout, Net::OpenTimeout) { begin TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) rescue => e # ... end } # ... end private :connect MJCOFUIUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM -FUTUBLFBMPPLBU/FU)551 5IFNFUIPESFTQPOTJCMFGPSBUUFNQUJOH B5$1DPOOFDUJPOJT/FU)551DPOOFDU 5$14PDLFUPQFO BOBMJBTGPS5$14PDLFUOFXTUBSUTBDPOOFDUJPO

Slide 183

Slide 183 text

/FU)551DPOOFDU def connect # ... s = Timeout.timeout(@open_timeout, Net::OpenTimeout) { begin TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) rescue => e # ... end } # ... end private :connect )FSF UJNFPVUHFNJTVTFEUPNBOBHFUIFDPOOFDUJPO UJNFPVU*GUIFUJNFUBLFOGPSUIFDPOOFDUJPOBUUFNQU FYDFFETUIFTQFDJ fi FEUJNFPVUWBMVF  /FU0QFO5JNFPVUJTSBJTFE .BOBHFUJNFPVU /FU0QFO5JNFPVUXJUIDPOOFDUUJNFPVU MJCOFUIUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 184

Slide 184 text

/FU)551DPOOFDU def connect # ... s = Timeout.timeout(@open_timeout, Net::OpenTimeout) { begin TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) rescue => e # ... end } # ... end private :connect 5IJTDPEFBOEUIFUFTUXFSFXPSLJOHBTFYQFDUFE CFGPSF)&WXBTJOUSPEVDFE4PXIBU`THPJOHPOOPX def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| # ... conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) # ... } # ... end UFTUOFUIUUQUFTU@IUUQSC MJCOFUIUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 185

Slide 185 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH -FU`TUBLFMPPLBUUIFUFTUDPEFBHBJO 5IFTFSWFSJTTUBSUFECZQBTTJOHMPDBMIPTU UP5$14FSWFSOFX 4UBSUB5$1TFSWFS XJUIIPTUOBNFMPDBMIPTU UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 186

Slide 186 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end *OUIFCBDLHSPVOE UIFTFSWFSSFTPMWFTUIFIPTUOBNF MPDBMIPTUBOECJOETJUTMJTUFOJOHTPDLFU UPPOFPGUIFSFTPMWFEBEESFTTFT CJOE 0OFPGUIFSFTPMWFEBEESFTTFT "MJTUFOJOHTPDLFU 4FSWFS "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 187

Slide 187 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end 0OBEVBMTUBDLIPTU UIFTFSWFSCJOETUP FJUIFS *1W PS *1W  EFQFOEJOHPOXIJDIPOFJTSFTPMWFE fi STU  "MJTUFOJOHTPDLFU 4FSWFS  PS 8IJDIFWFSSFTPMWFT fi STU CJOE 8IFUIFS*1WPS*1WHFUTSFTPMWFE fi STU EFQFOETPOUIF04BOEOFUXPSLTFUUJOHT "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 188

Slide 188 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end *OUIFFOWJSPONFOUXIFSFUIFUFTUXBTGBJMJOH  UIFTFSWFSFOEFEVQCJOEJOHUP *1W   "MJTUFOJOHTPDLFU 4FSWFS *OUIFFOWJSPONFOU XIFSFUIFUFTUXBTGBJMJOH CJOE "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 189

Slide 189 text

0OUIFPUIFSTJEF JGUIFDMJFOUTVDDFTTGVMMZSFTPMWFTCPUI *1WBOE*1WBEESFTTFT  JUGPMMPXTUIF)&WTQFDJ fi DBUJPOBOEQSJPSJUJ[FTDPOOFDUJOH UPUIF*1WBEESFTT 4FSWFS 4UBSUBDPOOFDUJPOBUUFNQUUP 5$14PDLFUOFX  "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH 3FTPMWFECPUI BOE

Slide 190

Slide 190 text

"OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH )PXFWFS UIFSFJTOPTFSWFSMJTUFOJOHPO *1W  TPUIF*1WDPOOFDUJPOBUUFNQUGBJMTJOUIJTDBTF 4UBSUBDPOOFDUJPOBUUFNQUUP 5$14PDLFUOFX 5IFBUUFNQUGBJMT 4FSWFS 

Slide 191

Slide 191 text

"OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH 4JODFUIFDMJFOULOPXTBO*1WBEESFTT JUTIPVME GBMMCBDLBOEJOJUJBUFBDPOOFDUJPOBUUFNQUUPJUJNNFEJBUFMZ 4UBSUBDPOOFDUJPOBUUFNQUUP 5$14PDLFUOFX 5IFBUUFNQUGBJMT 4FSWFS  8BOUUPSFUSZXJUI

Slide 192

Slide 192 text

)PXFWFS JOSFBMJUZ  $POOFDUJPO"UUFNQU%FMBZTUBSUTBUUIJTQPJOU  BOEJUJTBCPVUUPXBJUNTCFGPSFBUUFNQUJOHUIF DPOOFDUJPOUPUIF*1WBEESFTT 4UBSUBDPOOFDUJPOBUUFNQUUP 5$14PDLFUOFX 5IFBUUFNQUGBJMT 4FSWFS  "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH 8BJUNT

Slide 193

Slide 193 text

def test_timeout_during_HTTP_session_write th = nil TCPServer.open('localhost', 0) {|server| port = server.addr[1] conn = Net::HTTP.new('localhost', port) conn.write_timeout = EnvUtil.apply_timeout_scale(0.01) conn.open_timeout = EnvUtil.apply_timeout_scale(0.1) th = Thread.new do assert_raise(Net::WriteTimeout) do assert_warning(/Content-Type did not set/) do conn.post('/', "a"*50_000_000) end end end assert th.join(EnvUtil.apply_timeout_scale(10)) } # ... end UFTUOFUIUUQUFTU@IUUQSC "TPG13IUUQTHJUIVCDPNSVCZSVCZQVMM 5IJTNFBOTUIBUXIJMFXBJUJOHGPSUIFNT $POOFDUJPO"UUFNQU%FMBZ UIFNT DPOOFDUUJNFPVUXBTCFJOHUSJHHFSFE DPOOFDUUJNFPVUNT "OTXFSJOHUIFRVFTUJPO8IZJTUIFUFTUGBJMJOH 5IFNTUJNFPVUFYQJSFTEVSJOHUIFNTXBJU 5IF8JOEPXTTQFDJ fi DQBSUTBSFPNJUUFE

Slide 194

Slide 194 text

3FTPMWJOHUIFUJNFPVUJTTVF if (status > 0) { /* check for connection */ if (in_progress_fds(arg->connection_attempt_fds_size)) { for (/* If there are sockets with a confirmed connection state */) { // Check for connection } if (connected_fd >= 0) break; if (!in_progress_fds(arg->connection_attempt_fds_size)) { if (/* No address candidates available and finished name resolution */) { // Raise an error and exit } connection_attempt_delay_expires_at = NULL; user_specified_connect_timeout_at = NULL; } } // ... FYUTPDLFUJQTPDLFUD 4P *SFTFUDPOOFDUJPO@BUUFNQU@EFMBZ@BUXIFOBMM QSFWJPVTDPOOFDUJPOBUUFNQUTIBWFGBJMFE BMMPXJOHUIF OFYUDPOOFDUJPOUPTUBSUXJUIPVUXBJUJOHNT 3FTFUDPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BU 5IFSFJTOPTVDDFTTGVMMZDPOOFDUFETPDLFU  BOEOPTPDLFUDVSSFOUMZBUUFNQUJOHUPDPOOFDU

Slide 195

Slide 195 text

.FSHFE13 XIJDIJODMVEFTUIJT fi Y IUUQTHJUIVCDPNSVCZSVCZQVMM /PWFNCFS 

Slide 196

Slide 196 text

.FSHFE13 XIJDIBMTPJODMVEFTUIJT fi Y /PWFNCFS  IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 197

Slide 197 text

3VCZ$*HPUJOOFSQFBDF All CIs passed

Slide 198

Slide 198 text

.FSHFE13 UPTPMWFTBNFQSPCMFNJO4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 199

Slide 199 text

%FDFNCFS 

Slide 200

Slide 200 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO %FDFNCFS 

Slide 201

Slide 201 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO 4PDLFUGBTU@GBMMCBDLTFHGBVMUTXIFO GETBSF'%@4&54*;& IUUQTCVHTSVCZMBOHPSHJTTVFT

Slide 202

Slide 202 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO 4PDLFUGBTU@GBMMCBDLTFHGBVMUTXIFO GETBSF'%@4&54*;& *GUIFOVNCFSPG fi MFEFTDSJQUPS GE  PQFOFECZ5$14PDLFUOFXFYDFFET'%@4&54*;& BTFHNFOUBUJPOGBVMUXJMMPDDVS 5IF fi MFEFTDSJQUPS GE MJNJUTFUCZUIFIPTU

Slide 203

Slide 203 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end IUUQTCVHTSVCZMBOHPSHJTTVFT 3FQSPEVDUJPODPEFCZ!KIBXUIPSO

Slide 204

Slide 204 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end IUUQTCVHTSVCZMBOHPSHJTTVFT 3FQSPEVDUJPODPEFCZ!KIBXUIPSO 0QFOFOPVHI fi MFTJOBEWBODFTPUIBU UIFUPUBMOVNCFSPGGETDPNFTDMPTF UPUIFTZTUFN`T'%@4&54*;&MJNJU

Slide 205

Slide 205 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end IUUQTCVHTSVCZMBOHPSHJTTVFT 3FQSPEVDUJPODPEFCZ!KIBXUIPSO 4UBSUBTFSWFS

Slide 206

Slide 206 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end IUUQTCVHTSVCZMBOHPSHJTTVFT 3FQSPEVDUJPODPEFCZ!KIBXUIPSO 4UBSUTFWFSBMOFXDPOOFDUJPOTUP UIFTFSWFSVTJOH5$14PDLFUPQFO 5$14PDLFUOFX

Slide 207

Slide 207 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end IUUQTCVHTSVCZMBOHPSHJTTVFT 3FQSPEVDUJPODPEFCZ!KIBXUIPSO 8IFOUIFUPUBMOVNCFSPG BMSFBEZPQFOFE fi MFT UIFTPDLFUT PQFOFECZ5$14PDLFUOFX SFBDIFTFYDFFET'%@4&54*;& 4UBSUTFWFSBMOFXDPOOFDUJPOTUP UIFTFSWFSVTJOH5$14PDLFUPQFO 5$14PDLFUOFX

Slide 208

Slide 208 text

"OJTTVFSFQPSUFECZ!KIBXUIPSO $ ulimit -n 2048 $ ruby test.rb # # # ... ================================================================= ==3180778==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ae35aadc580 at pc 0x7ae35b1b7449 bp 0x7fffc9af1af0 sp 0x7fffc9af1ae8 READ of size 8 at 0x7ae35aadc580 thread T0 #0 0x7ae35b1b7448 in init_fast_fallback_inetsock_internal /.../ruby/ext/socket/ipsocket.c:912:17 #1 0x60462ff14879 in rb_ensure /.../ruby/eval.c:1053:18 #2 0x7ae35b1b41b9 in rsock_init_inetsock /.../ruby/ext/socket/ipsocket.c:1315:20 #3 0x7ae35b1bae9a in tcp_init /.../ruby/ext/socket/tcpsocket.c:91:12 ... IUUQTCVHTSVCZMBOHPSHJTTVFT A segmentation fault occurs!!

Slide 209

Slide 209 text

"GVODUJPOPGUIFDBVTFPGUIFQSPCMFN static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } 5IFDBVTFPGUIJTJTTVFXBT UIFGVODUJPOQSFWJPVTMZJOUSPEVDFE

Slide 210

Slide 210 text

"GVODUJPOPGUIFDBVTFPGUIFQSPCMFN static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } *OTJEFUIJTGVODUJPO DBMMTFMFDU  XBJUGPSFJUIFS OBNFSFTPMVUJPOPSBDPOOFDUJPOUPDPNQMFUF CZ NPOJUPSJOHCPUIUIFQJQFXBJUJOHGPSOBNFSFTPMVUJPO OPUJ fi DBUJPOTBOEUIFTPDLFUTBUUFNQUJOHUPDPOOFDU 5IFQJQFXBJUJOHGPSOBNFSFTPMVUJPOOPUJ fi DBUJPOT 5IFTPDLFUTXBJUJOHUPDPOOFDU

Slide 211

Slide 211 text

static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } "GVODUJPOPGUIFDBVTFPGUIFQSPCMFN *OBTFOTF TFMFDU  JTUIFNPTUJNQPSUBOUTZTUFNDBMM XIFOJUDPNFTUPJNQMFNFOUJOHUIF)&WTQFDJ fi DBUJPO 5IFNPTUJNQPSUBOUTZTUFNDBMMGPS)&W

Slide 212

Slide 212 text

static void * wait_fast_fallback(void *ptr) { struct wait_fast_fallback_arg *arg = (struct wait_fast_fallback_arg *)ptr; int status; status = select(arg->nfds, arg->readfds, arg->writefds, NULL, arg->delay); arg->status = status; if (errno == EINTR) *arg->cancelled = true; return 0; } "GVODUJPOPGUIFDBVTFPGUIFQSPCMFN 5IFQSPCMFNJTUIBUTFMFDU  DBOOPUNPOJUPS GETOVNCFSHSFBUFSUIBO'%@4&54*;& /PUTVQQPSUFECFZPOE'%@4&54*;&

Slide 213

Slide 213 text

TFMFDU  Š-JOVYNBOVBMQBHF IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM 5IJTMJNJUBUJPOJTBDUVBMMZEPDVNFOUFEJOUIFNBOVBM GPSTFMFDU  'PSFYBNQMF IFSF`TUIFSFMFWBOUTFDUJPO GSPNUIFNBOPG-JOVY DESCRIPTION WARNING: select() can monitor only fi le descriptors numbers that are less than FD_SETSIZE (1024)—an unreasonably low limit for many modern applications—and this limitation will not change. All modern applications should instead use poll(2) or epoll(7), which do not su ff er this limitation.

Slide 214

Slide 214 text

TFMFDU  Š-JOVYNBOVBMQBHF IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM DESCRIPTION WARNING: select() can monitor only fi le descriptors numbers that are less than FD_SETSIZE (1024)—an unreasonably low limit for many modern applications—and this limitation will not change. All modern applications should instead use poll(2) or epoll(7), which do not su ff er this limitation.

Slide 215

Slide 215 text

TFMFDU  Š-JOVYNBOVBMQBHF IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM NOTES The following header also provides the fd_set type: . An fd_set is a fi xed size bu ff er. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in unde fi ned behavior. Moreover, POSIX requires fd to be a valid fi le descriptor. '%@$-3 BOE'%@4&5 BSFNBDSPT UIBUBSFFYFDVUFECFGPSFDBMMJOHTFMFDU 

Slide 216

Slide 216 text

TFMFDU  Š-JOVYNBOVBMQBHF IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM NOTES The following header also provides the fd_set type: . An fd_set is a fi xed size bu ff er. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in unde fi ned behavior. Moreover, POSIX requires fd to be a valid fi le descriptor. 5IJTJTBQSPCMFN

Slide 217

Slide 217 text

5IFTFMFDU  QSPCMFN 5PTPMWFUIJTJTTVF  XFOFFEUPQFSGPSNUIFQSPDFTTJOHDVSSFOUMZEPOF CZTFMFDU  VTJOHBXBZPUIFSUIBOTFMFDU  

Slide 218

Slide 218 text

TFMFDU  Š-JOVYNBOVBMQBHF IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM 5IFNBOPG-JOVYSFDPNNFOETVTJOH FJUIFSQPMM  PSFQPMM  GPSUIJTQVSQPTF DESCRIPTION WARNING: select() can monitor only fi le descriptors numbers that are less than FD_SETSIZE (1024)—an unreasonably low limit for many modern applications—and this limitation will not change. All modern applications should instead use poll(2) or epoll(7), which do not su ff er this limitation.

Slide 219

Slide 219 text

TFMFDU  Š-JOVYNBOVBMQBHF DESCRIPTION WARNING: select() can monitor only fi le descriptors numbers that are less than FD_SETSIZE (1024)—an unreasonably low limit for many modern applications—and this limitation will not change. All modern applications should instead use poll(2) or epoll(7), which do not su ff er this limitation. IUUQTNBOPSHMJOVYNBOQBHFTNBOTFMFDUIUNM FQPMM  JTBO"1*TQFDJ fi DUP-JOVYFOWJSPONFOUT 4JODF5$14PDLFUOFXXJUI)&WJTJOUFOEFEUPXPSLPO BMMFOWJSPONFOUTXIFSFQUISFBETBSFBWBJMBCMF DIPPTJOH QPMM  JTUIFNPSFSFBTPOBCMFPQUJPOJOUIJTDBTF

Slide 220

Slide 220 text

4PMWJOHUIFTFMFDU  QSPCMFN *MPPLFEJOUPXIFUIFS TFMFDU  DPVMECFSFQMBDFEXJUIQPMM  CZFYBNJOJOH UIFEJ ff FSFODFTCFUXFFOUIFTFTZTUFNDBMMT "TBSFTVMU *GPVOEUIBUUIFJSEJ ff FSFODFTBSFBTGPMMPXT

Slide 221

Slide 221 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  'VODUJPOTJHOBUVSFT int poll( struct pollfd *fds, nfds_t nfds, int timeout ); int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *utimeout );

Slide 222

Slide 222 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  5ZQFTPGUBSHFUTUIFZDBONPOJUPS int poll( struct pollfd *fds, nfds_t nfds, int timeout ); int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *utimeout ); +VTUTPNFGE@TFUT struct pollfd { int fd; short events; short revents:
 };

Slide 223

Slide 223 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  5ZQFTPGFWFOUTUIFZDBONPOJUPS ɾPOLLIN ɾPOLLOUT ɾPOLLERR ɾPOLLHUP ɾPOLNVAL ɾreadfds ɾwritefds ɾexceptfds int poll( struct pollfd *fds, nfds_t nfds, int timeout ); int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *utimeout );

Slide 224

Slide 224 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  )PXUPTQFDJGZUIFGETUPNPOJUPS int fd; fd_set set; FD_ZERO(&set); FD_SET(fd, &set); int fd; struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLIN | POLLOUT; int poll( struct pollfd *fds, nfds_t nfds, int timeout ); int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *utimeout );

Slide 225

Slide 225 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  5JNFPVUSFTPMVUJPO NJMMJTFDPOET struct timeval { time_t tv_sec; suseconds_t tv_usec
 }; int poll( struct pollfd *fds, nfds_t nfds, int timeout ); int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *utimeout );

Slide 226

Slide 226 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  $PODMVTJPO 1SFUUZNVDIFWFSZUIJOHJTEJ ff FSFOU

Slide 227

Slide 227 text

5IFEJ ff FSFODFTCFUXFFOTFMFDU  BOEQPMM  $PODMVTJPO 1SFUUZNVDIFWFSZUIJOHJTEJ ff FSFOU ➡︎ 4JHOJ fi DBOUBNPVOUPGDPEFXJMMOFFEUPCFSFXSJUUFO ɹ5IFQSPCMFNJT JU`TBMSFBEZ%FDFNCFSUI ɹ -FTTUIBOEBZTMFGUVOUJMUIFSFMFBTFPG3VCZ  *`EMJLFUPIBWFUIFDIBOHFTNFSHFEBOEUIFOMFU3VCZ$* SVOGPSBEFDFOUBNPVOUPGUJNFUPNPOJUPSUIFSFTVMUT

Slide 228

Slide 228 text

5IJTJTTVFEPFTOPUPDDVSXJUI4PDLFUUDQ BTJNQMFNFOUFEJO3VCZ )PXJTJUIBOEMFEJO4PDLFUUDQ

Slide 229

Slide 229 text

class Socket # ... def self.tcp(...) # ... hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, is_windows_environment ? connecting_sockets.keys : nil, second_to_timeout(current_clock_time, ends_at), ) # ... end # ... end *O4PDLFUUDQ *0TFMFDUJTVTFEUPXBJUGPS OBNFSFTPMVUJPOBOEDPOOFDUJPODPNQMFUJPO 4PIPXJTJUIBOEMFEJO4PDLFUUDQ )PXJTJUIBOEMFEJO4PDLFUUDQ

Slide 230

Slide 230 text

void Init_IO(void) { // ... rb_cIO = rb_define_class("IO", rb_cObject); // ... rb_define_singleton_method(rb_cIO, "select", rb_f_select, -1); // ... } 5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU JPD *GPVOEUIBU*0TFMFDUJTJNQMFNFOUFEJOUFSOBMMZ JO3VCZBTSC@G@TFMFDU %F fi OFSC@G@TFMFDUBT*0TFMFDU %F fi OF*0DMBTT

Slide 231

Slide 231 text

$BMM4UBDLPG*0TFMFDU *0TFMFDU  ➡︎ SC@G@TFMFDU  ➡︎ SC@FOTVSF  ➡︎ TFMFDU@DBMM  ➡︎ TFMFDU@JOUFSOBM  ➡︎ SC@UISFBE@GE@TFMFDU  ➡︎ TFMFDU@FOE 5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU 5IJTGVODUJPODBMMTSC@UISFBE@GE@TFMFDU  BOJOUFSOBM3VCZGVODUJPO

Slide 232

Slide 232 text

int rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except, struct timeval *timeout) { // ... BLOCKING_REGION(set->th, { struct timeval tv; if (!RUBY_VM_INTERRUPTED(set->th->ec)) { result = native_fd_select(set->max, set->rset, set->wset, set->eset, rb_hrtime2timeval(&tv, to), set->th); if (result < 0) lerrno = errno; } }, ubf_select, set->th, TRUE); // ... } SC@UISFBE@GE@TFMFDUUIFODBMMTOBUJWF@GE@TFMFDU 5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU

Slide 233

Slide 233 text

5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU ɾUISFBE@QUISFBED 5IFEF fi OJUJPOPGOBUJWF@GE@TFMFDUEJ ff FST EFQFOEJOHPOXIFUIFSUIFFOWJSPONFOUTVQQPSUT QUISFBETPSJTSVOOJOHPO8JOEPXT static int native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th) static int native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th) ɾUISFBE@XJOD

Slide 234

Slide 234 text

5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU static int native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th) { return rb_fd_select(n, readfds, writefds, exceptfds, timeout); } UISFBE@QUISFBED *OFOWJSPONFOUTXJUIQUISFBET  JUJOUFSOBMMZDBMMTSC@GE@TFMFDU

Slide 235

Slide 235 text

ɾJODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI 5IFJOUFSOBMJNQMFNFOUBUJPOPG*0TFMFDU SC@GE@TFMFDUBMTPIBTEJ ff FSFOUEF fi OJUJPOTEFQFOEJOH PO04'PSDFSUBJOWFSTJPOTPG04 JUJTEF fi OFEJO MBSHFTJ[FIGPSPUIFST JUJTEF fi OFEJOQPTJYI int rb_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout) #define rb_fd_select select ɾJODMVEFSVCZJOUFSOBMJOUFSOTFMFDUQPTJYI

Slide 236

Slide 236 text

5BSHFU04WFSTJPOTGPSMBSHFTJ[FI /** * ... * * - Linux 2.2.12 (?) * * - NetBSD 1.2 (src/sys/kern/sys_generic.c:1.25) * ... * - FreeBSD 2.2 (src/sys/kern/sys_generic.c:1.19) * * - OpenBSD 2.0 (src/sys/kern/sys_generic.c:1.4) * ... * - Solaris 8 has `select_large_fdset` * * - Mac OS X 10.7 (Lion) * ... */ )FSFBSFUIFMJTUPG04WFSTJPOT XIFSFUIFMBSHFTJ[FIEF fi OJUJPOJTVTFE JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 237

Slide 237 text

/** * ... * * - Linux 2.2.12 (?) * * - NetBSD 1.2 (src/sys/kern/sys_generic.c:1.25) * ... * - FreeBSD 2.2 (src/sys/kern/sys_generic.c:1.19) * * - OpenBSD 2.0 (src/sys/kern/sys_generic.c:1.4) * ... * - Solaris 8 has `select_large_fdset` * * - Mac OS X 10.7 (Lion) * ... */ 'PSNPTUNPEFSO DPNNPOMZVTFE04WFSTJPOT  UIFEF fi OJUJPOJOMBSHFTJ[FIJTUIFPOFUIBUHFUTVTFE 5BSHFU04WFSTJPOTGPSMBSHFTJ[FI JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 238

Slide 238 text

/** * ... * * Several Unix platforms support file descriptors bigger than FD_SETSIZE in * `select(2)` system call. * * ... (The target OS versions) ... * * When `fd_set` is not big enough to hold big file descriptors, it should be * allocated dynamically. Note that this assumes `fd_set` is structured as * bitmap. * * `rb_fd_init` allocates the memory. * `rb_fd_term` frees the memory. * `rb_fd_set` may re-allocate bitmap. * * So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`. */ 8IBUMBSHFTJ[FIUFMMT )FSF`TXIBU`TXSJUUFOJOMBSHFTJ[FI JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 239

Slide 239 text

/** * ... * * Several Unix platforms support file descriptors bigger than FD_SETSIZE in * `select(2)` system call. * * ... (The target OS versions) ... * * When `fd_set` is not big enough to hold big file descriptors, it should be * allocated dynamically. Note that this assumes `fd_set` is structured as * bitmap. * * `rb_fd_init` allocates the memory. * `rb_fd_term` frees the memory. * `rb_fd_set` may re-allocate bitmap. * * So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`. */ 8IBUMBSHFTJ[FIUFMMT JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 240

Slide 240 text

/** * ... * * Several Unix platforms support file descriptors bigger than FD_SETSIZE in * `select(2)` system call. * * ... (The target OS versions) ... * * When `fd_set` is not big enough to hold big file descriptors, it should be * allocated dynamically. Note that this assumes `fd_set` is structured as * bitmap. * * `rb_fd_init` allocates the memory. * `rb_fd_term` frees the memory. * `rb_fd_set` may re-allocate bitmap. * * So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`. */ JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI 8IBUMBSHFTJ[FIUFMMT  GE@TFUTUPSFTUIF fi MFEFTDSJQUPSTUPCFNPOJUPSFE

Slide 241

Slide 241 text

5IFJNQMFNFOUBUJPOPGSC@GE@TFMFDU int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout) { fd_set *r = NULL, *w = NULL, *e = NULL; if (readfds) { rb_fd_resize(n - 1, readfds); r = rb_fd_ptr(readfds); } if (writefds) { rb_fd_resize(n - 1, writefds); w = rb_fd_ptr(writefds); } if (exceptfds) { rb_fd_resize(n - 1, exceptfds); e = rb_fd_ptr(exceptfds); } return select(n, r, w, e, timeout); } UISFBED

Slide 242

Slide 242 text

int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout) { fd_set *r = NULL, *w = NULL, *e = NULL; if (readfds) { rb_fd_resize(n - 1, readfds); r = rb_fd_ptr(readfds); } if (writefds) { rb_fd_resize(n - 1, writefds); w = rb_fd_ptr(writefds); } if (exceptfds) { rb_fd_resize(n - 1, exceptfds); e = rb_fd_ptr(exceptfds); } return select(n, r, w, e, timeout); } 5IJTGVODUJPONBLFTVTFPGUIFTUSVDUSC@GETFU@U 5IFJNQMFNFOUBUJPOPGSC@GE@TFMFDU TUSVDUSC@GETFU@UTBSFVTFE UISFBED

Slide 243

Slide 243 text

TUSVDUSC@GETFU@U /** * The data structure which wraps the fd_set bitmap used by select(2). This * allows Ruby to use FD sets larger than that allowed by historic limitations * on modern platforms. */ typedef struct { int maxfd; /**< Maximum allowed number of FDs. */ fd_set *fdset; /**< File descriptors buffer */ } rb_fdset_t; JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 244

Slide 244 text

/** * The data structure which wraps the fd_set bitmap used by select(2). This * allows Ruby to use FD sets larger than that allowed by historic limitations * on modern platforms. */ typedef struct { int maxfd; /**< Maximum allowed number of FDs. */ fd_set *fdset; /**< File descriptors buffer */ } rb_fdset_t; TUSVDUSC@GETFU@U TUSVDUSC@GETFU@UXSBQTUIFGE@TFU UPCFQBTTFEUPTFMFDU   5IFGE@TFUUPCFQBTTFEUPTFMFDU   JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI

Slide 245

Slide 245 text

/** * The data structure which wraps the fd_set bitmap used by select(2). This * allows Ruby to use FD sets larger than that allowed by historic limitations * on modern platforms. */ typedef struct { int maxfd; /**< Maximum allowed number of FDs. */ fd_set *fdset; /**< File descriptors buffer */ } rb_fdset_t; "OEJUIBTBDPNNFOU JODMVEFSVCZJOUFSOBMJOUFSOTFMFDUMBSHFTJ[FI TUSVDUSC@GETFU@U

Slide 246

Slide 246 text

5IFJNQMFNFOUBUJPOPGSC@GE@TFMFDU int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout) { fd_set *r = NULL, *w = NULL, *e = NULL; if (readfds) { rb_fd_resize(n - 1, readfds); r = rb_fd_ptr(readfds); } if (writefds) { rb_fd_resize(n - 1, writefds); w = rb_fd_ptr(writefds); } if (exceptfds) { rb_fd_resize(n - 1, exceptfds); e = rb_fd_ptr(exceptfds); } return select(n, r, w, e, timeout); } SC@GE@TFMFDUEZOBNJDBMMZBMMPDBUFTPSFYQBOETUIF CJUNBQSFHJPOTGPSUIFNPOJUPSFEGE@TFU BDDPSEJOHUPUIFNBYJNVNGEOVNCFS UISFBED

Slide 247

Slide 247 text

5IFJNQMFNFOUBUJPOPGSC@GE@TFMFDU int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout) { fd_set *r = NULL, *w = NULL, *e = NULL; if (readfds) { rb_fd_resize(n - 1, readfds); r = rb_fd_ptr(readfds); } if (writefds) { rb_fd_resize(n - 1, writefds); w = rb_fd_ptr(writefds); } if (exceptfds) { rb_fd_resize(n - 1, exceptfds); e = rb_fd_ptr(exceptfds); } return select(n, r, w, e, timeout); } BOEQBTTFTQPJOUFSTUPUIFTFSFHJPOTUPTFMFDU   UIFSFCZFOBCMJOHTVQQPSUGPS fi MFEFTDSJQUPST UIBUFYDFFE'%@4&54*;& $BMMTFMFDU  XJUIUIFQPJOUFST UISFBED

Slide 248

Slide 248 text

$BMM4UBDLPG*0TFMFDU *0TFMFDU  ➡︎ SC@G@TFMFDU  ➡︎ SC@FOTVSF  ➡︎ TFMFDU@DBMM  ➡︎ TFMFDU@JOUFSOBM  ➡︎ SC@UISFBE@GE@TFMFDU  ➡︎ OBUJWF@GE@TFMFDU  ➡︎ SC@GE@TFMFDU  ➡︎ TFMFDU@FOE 4P EPFTO`UUIBUNFBO5$14PDLFUOFXDPVMEKVTUDBMM SC@GE@TFMFDUJOTUFBEPGDBMMJOHTFMFDU  EJSFDUMZ This seems like a good fit!

Slide 249

Slide 249 text

%FDFNCFS 

Slide 250

Slide 250 text

%FDFNCFS  .FSHFE13 UIBUSFQMBDFTTFMFDU  XJUISC@UISFBE@GE@TFMFDU  BXSBQQFS"1*BSPVOESC@GE@TFMFDU UPTPMWFUIJTJTTVF IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 251

Slide 251 text

3FTPMWFEUIFTFMFDU  JTTVF 5IJTDIBOHFBMMPXFENFUPSFNPWFUIFQSPDFTTJOHUIBUIBECFFO OFDFTTBSZGPSDBMMJOHTFMFDU  XIJDIJOUVSONBEFUIFDPEF TMJHIUMZTJNQMFSPWFSBMM IUUQTHJUIVCDPNSVCZSVCZQVMM  

Slide 252

Slide 252 text

%FDFNCFS 

Slide 253

Slide 253 text

5IFMBTU%FW.FFUJOHJOUIFZFBS %FDFNCFS 

Slide 254

Slide 254 text

0OUIJTEBZ *CSPVHIUVQUIFUPQJDPGIPXUPDPOUSPM UIFFOBCMJOHBOEEJTBCMJOHPG)&W "1*GPS(MPCBMMZ&OBCMJOH%JTBCMJOH )BQQZ&ZFCBMMT7FSTJPOJOUIF4PDLFU$MBTT 5IFMBTU%FW.FFUJOHJOUIFZFBS IUUQTCVHTSVCZMBOHPSHJTTVFT

Slide 255

Slide 255 text

5IFMBTU%FW.FFUJOHJOUIFZFBS "TBSFTVMUPGUIFEJTDVTTJPO  XFEFDJEFEUPQSPWJEFUIFGPMMPXJOHXBZTUPDPOUSPMJU ɾ"OBSHVNFOUUPUIFNFUIPE ɾ"OBDDFTTPSNFUIPEPOUIF4PDLFUDMBTT ɾ"OFOWJSPONFOUWBSJBCMF Socket.tcp(host, port, fast_fallback: false) # Disable TCPSocket.new(host, port, fast_fallback: false) # Disable Socket.tcp_fast_fallback = false # Disable TCP_NO_FAST_FALLBACK = 1 # Disable

Slide 256

Slide 256 text

5IFMBTU%FW.FFUJOHJOUIFZFBS "UUIFTBNFUJNF  JUXBTBMTPEFDJEFEUIBU)&WXPVMECFFOBCMFE CZEFGBVMUJO3VCZ

Slide 257

Slide 257 text

.FSHFE13 XIJDIJODMVEFTUIFDIBOHFTCBTFEPOUIJTEFDJTJPO IUUQTHJUIVCDPNSVCZSVCZQVMM %FDFNCFS 

Slide 258

Slide 258 text

8SPUFBOJOUSPEVDUJPOUP)&W JO/&84NE %FDFNCFS 

Slide 259

Slide 259 text

%FDFNCFS  8SPUFBOJOUSPEVDUJPOUP)&W JOUIFSFMFBTFOPUF

Slide 260

Slide 260 text

%FDFNCFS 

Slide 261

Slide 261 text

+45 %FDFNCFS BUBN

Slide 262

Slide 262 text

+45 %FDFNCFS BUBN .FSHFE13 GPS fi YJOHBCVHGPVOEBUUIFMBTUNJOVUF IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 263

Slide 263 text

5IBUBGUFSOPPO

Slide 264

Slide 264 text

IUUQTUXJUUFSDPNOBMTITUBUVT 3VCZ  3FMFBTFE

Slide 265

Slide 265 text

IUUQTXXXSVCZMBOHPSHFOOFXTSVCZSFMFBTFE BEET)BQQZ&ZFCBMMT7FSTJPOTVQQPSU ɹUPTPDLFUMJCSBSZ

Slide 266

Slide 266 text

5IFPVUDPNFPGJOUSPEVDJOH)&W 5IFSFBTPOXIZ)&WXBTJOUSPEVDFEJT

Slide 267

Slide 267 text

5IFPVUDPNFPGJOUSPEVDJOH)&W 'PSFYBNQMF JG*1WOBNFSFTPMVUJPOGBJMFEPSBDPOOFDUJPO UPUIFTFSWFSDPVMEO`UCFFTUBCMJTIFE  UIFSFXBTBOJTTVFXIFSFJUDPVMEO`UJNNFEJBUFMZGBMMCBDLUP *1W 4P EJEUIJTDIBOHFBDUVBMMZTPMWFUIBUJTTVF 4FSWFS 5IFBUUFNQUDPOUJOVFT $BOOPUTUBSUBOFXBUUFNQUUP*1W FH 4UBSUBDPOOFDUJPOBUUFNQUUP*1W 4PDLFUUDQ 5$14PDLFUOFX *1W *1W

Slide 268

Slide 268 text

5IFPVUDPNFPGJOUSPEVDJOH)&W 5PWFSJGZUIFSFTVMUT MFUTNFBTVSFUIFFYFDVUJPOUJNFPG 5$14PDLFUOFXJOBEVNNZFOWJSPONFOUXIFSFSFTPMVUJPO JTEFMJCFSBUFMZEFMBZFE %/4TFSWFS %FTUJOBUJPOTFSWFS 5$14PDLFUOFX 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT ʁ

Slide 269

Slide 269 text

5IFPVUDPNFPGJOUSPEVDJOH)&W require "rubydns" RubyDNS.run_server([[:udp, "0.0.0.0", 53], [:udp, "::", 53]]) do match("example.com", Resolv::DNS::Resource::IN::A) do |tx| tx.respond!("127.0.0.1") end match("example.com", Resolv::DNS::Resource::IN::AAAA) do |tx| sleep Float::INFINITY tx.respond!("::1") end otherwise do |query| tx.fail!(:NXDomain) end end *QSFQBSFEB%/4TFSWFSUIBUOFWFSSFUVSOTBOZ*1W BEESFTTFT CVUSFTQPOETJNNFEJBUFMZXJUIBO*1W BEESFTT /FWFSSFUVSOTBO*1WBEESFTT 3FUVSOTBO*1WBEESFTTJNNFEJBUFMZ

Slide 270

Slide 270 text

$ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: false) > " 5IFPVUDPNFPGJOUSPEVDJOH)&W 8JUIUIJT%/4TFSWFSQSPDFTTSVOOJOH   fi STUSVO5$14PDLFUOFXXJUI)&WEJTBCMFE *OUIJTDBTF 3VCZPO6CVOUV

Slide 271

Slide 271 text

$ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: false) > " # 0.06s user 0.01s system 0% cpu 15.086 total 5IFPVUDPNFPGJOUSPEVDJOH)&W JUUBLFTBCPVUTFDPOETGPSUIFNFUIPEUPDPNQMFUF 3VCZPO6CVOUV

Slide 272

Slide 272 text

$ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: false) > " # 0.06s user 0.01s system 0% cpu 15.086 total $ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: true) > " 5IFPVUDPNFPGJOUSPEVDJOH)&W 0OUIFPUIFSIBOE XIFO)&WJTFOBCMFE 3VCZPO6CVOUV

Slide 273

Slide 273 text

$ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: false) > " # 0.06s user 0.01s system 0% cpu 15.086 total $ time ruby -rsocket -e " > p TCPSocket.new('example.com', 4567, fast_fallback: true) > " # 0.05s user 0.01s system 52% cpu 0.114 total 5IFPVUDPNFPGJOUSPEVDJOH)&W UIFSFTVMUJTSFUVSOFEJOBCPVUTFDPOET *OBXPSTUDBTFTDFOBSJPMJLFUIJT FOBCMJOH)&W NBLFTUIFDPOOFDUJPOSPVHIMZUJNFTGBTUFS 132.3x faster! 3VCZPO6CVOUV

Slide 274

Slide 274 text

*NQBDUPOQFSGPSNBODF require "socket" require "benchmark" hostname = "www.ruby-lang.org" port = 80 Benchmark.bmbm do |x| x.report("fast_fallback: false") do 100.times { TCPSocket.new(hostname, port, fast_fallback: false).close } end x.report("fast_fallback: true") do 100.times { TCPSocket.new(hostname, port, fast_fallback: true).close } end end 0OUIFPUIFSIBOE  SFHBSEJOHUIFJNQBDUPOQFSGPSNBODF  SVOBCFODINBSLPWFSFYFDVUJPOT

Slide 275

Slide 275 text

*NQBDUPOQFSGPSNBODF $ time ruby benchmark.rb Rehearsal -------------------------------------------------------- fast_fallback: false 0.014033 0.078984 0.093017 ( 1.413951) fast_fallback: true 0.017588 0.097045 0.114633 ( 1.460664) ----------------------------------------------- total: 0.207650sec user system total real fast_fallback: false 0.018392 0.110852 0.129244 ( 1.466014) fast_fallback: true 0.020891 0.124054 0.144945 ( 1.473816) 'PSFYBNQMF XIFODPOOFDUJOHUPSVCZMBOHPSH  UIFBWFSBHFFYFDVUJPOUJNFXBTTFDPOET XJUI)&WEJTBCMFE BOETFDPOETXJUIJUFOBCMFE 3VCZPO6CVOUV

Slide 276

Slide 276 text

0UIFS$POTJEFSBUJPOT#FZPOE1FSGPSNBODF "TJEFGSPNQFSGPSNBODF  UIFSFNBZBMTPCFDBTFTXIFSF)&WJTOPUTVJUBCMF GPSDFSUBJOFOWJSPONFOUTPSVTFDBTFT FH ɾ8IFOUIFEFTUJOBUJPOTFSWFSMJNJUTNVMUJQMFTJNVMUBOFPVT ɹDPOOFDUJPOTGSPNUIFTBNF*1BEESFTT ɾ8IFOUIFDMJFOUIPTUIBTTUSJDUMJNJUTPOUIF ɹOVNCFSPGBWBJMBCMF fi MFEFTDSJQUPST

Slide 277

Slide 277 text

0UIFS$POTJEFSBUJPOT#FZPOE1FSGPSNBODF *OTVDIDBTFT  QMFBTFDPOTJEFSVTJOHUIFPQUJPOUPEJTBCMF)&W ɾ"OBSHVNFOUUPUIFNFUIPE ɾ"OBDDFTTPSNFUIPEPOUIF4PDLFUDMBTT ɾ"OFOWJSPONFOUWBSJBCMF Socket.tcp(host, port, fast_fallback: false) # Disable TCPSocket.new(host, port, fast_fallback: false) # Disable Socket.tcp_fast_fallback = false # Disable TCP_NO_FAST_FALLBACK = 1 # Disable

Slide 278

Slide 278 text

BOEUIFZBMMMJWFEIBQQJMZFWFSBGUFS 

Slide 279

Slide 279 text

BOEUIFZBMMMJWFEIBQQJMZFWFSBGUFS  ➡︎ /PURVJUF 4PNFJTTVFTIBWFCFFOSFQPSUFEBGUFSUIFSFMFBTF ŠTPNFPGUIFN* fi YFENZTFMG BOEPUIFSTXFSF fi YFECZGFMMPX3VCZJTUT

Slide 280

Slide 280 text

)BQQZ&ZFCBMMT7FSTJPOJTBMSFBEZ BQBSUPG3VCZ *IPQFUIBUBTJUDPOUJOVFTUPJNQSPWF XJUIJOUIFDPNNVOJUZ JUXJMMDPOUSJCVUF UPUIFGVSUIFSFWPMVUJPOPG3VCZ

Slide 281

Slide 281 text

0WFSUIFQBTUZFBS  UIF3VCZDPNNVOJUZIBWFUVSOFENFŠ B3VCZJTUXJUIBOJOUFSFTUJOOFUXPSLJOH  JOUPB3VCZDPNNJUUFS

Slide 282

Slide 282 text

"TBNFNCFSPGUIFDPNNVOJUZ  *`ECFIBQQZJGTPNFPOFMJTUFOJOHUPUIJTUBML FOETVQCFDPNJOHBGVUVSFUFBNNBUF  XPSLJOHUPHFUIFSPODIBMMFOHFTMJLFUIFTF

Slide 283

Slide 283 text

.BLJOH5$14PDLFUOFX)BQQZ 4QFDJBMUIBOLTUP !BLS !OBSVTF !KIBXUIPSO !ZVJLOL !HBDIBDPNQMFUF !ITCU !LBLVUBOJBOE3VCZDPNNJUUFST