Slide 1

Slide 1 text

"OBEWFOUVSFPG)BQQZ&ZFCBMMT .JTBLJ4IJPJ !TIJPJNN!DPF@ .BZ 3VCZ,BJHJ

Slide 2

Slide 2 text

QQTFMG .JTBLJ4IJPJ !TIJPJNN (JU)VC !DPF@ 5XJUUFS #TLZ 3BJMTBQQMJDBUJPOQSPHSBNNFSBU4.4$P -UE .FNCFSPG"TBLVTBSC "NJOUFSFTUFEJOOFUXPSLJOH

Slide 3

Slide 3 text

5IJTQSFTFOUBUJPOJTCBTFEPOUIFQSPKFDU *OUSPEVDUJPOPG)BQQZ&ZFCBMMT7FSTJPO 3'$ UPUIFTPDLFUMJCSBSZ XIJDIXBTTFMFDUFEGPS UIF3VCZ"TTPDJBUJPOHSBOUJO 3VCZ"TTPDJBUJPO(SBOUTFMFDUJPOSFTVMU IUUQTXXXSVCZPSKQFOOFXT

Slide 4

Slide 4 text

8IBUJT)BQQZ&ZFCBMMTʜ

Slide 5

Slide 5 text

#FGPSFEJTDVTTJOH)BQQZ&ZFCBMMT *XPVMEMJLFUPJOUSPEVDFTPNFJTTVFT DVSSFOUMZQSFTFOUJO3VCZTTPDLFUMJCSBSZ

Slide 6

Slide 6 text

3VCZTTPDLFUMJCSBSZ 3VCZTTPDLFUMJCSBSZJODMVEFTBNFUIPEUIBU SFUVSOTBTPDLFUDPOOFDUFEWJB5$1UPBTFSWFS 5IFTFNFUIPETBSFVTFEJOMJCSBSJFTTVDIBTOFUIUUQ OFUGUQBOEOFUJNBQ $MJFOU 4FSWFS $POOFDUJPOFTUBCMJTIFE 3FUVSOB4PDLFUPCKFDUDPOOFDUFEUPUIFUBSHFUTFSWFS &YFDVUFUIFNFUIPE

Slide 7

Slide 7 text

)PXTPDLFUMJCSBSZTNFUIPETXPSL 5IFZXPSLJOUFSOBMMZBTGPMMPXT %/44FSWFS 4FSWFS $MJFOU 4FSWFS XXXSVCZMBOHPSH

Slide 8

Slide 8 text

)PXTPDLFUMJCSBSZTNFUIPETXPSL 'JSTU RVFSZB%/4TFSWFSGPSBUBSHFUTFSWFST EPNBJOOBNFUPPCUBJOJUT*1BEESFTT %/44FSWFS 2VFSZ*1BEESFTTFT "OTXFS*1BEESFTTFT 4FSWFS $MJFOU 4FSWFS XXXSVCZMBOHPSH 5IF*1BEESFTTJT D

Slide 9

Slide 9 text

/FYU UIFZTUBSUBDPOOFDUJPOBUUFNQUUPUIFSFTPMWFE*1 BEESFTT )PXTPDLFUMJCSBSZTNFUIPETXPSL 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT D

Slide 10

Slide 10 text

*GUIFDPOOFDUJPOJTFTUBCMJTIFE UIFOJUSFUVSOTUIFTPDLFU DPOOFDUFEUPUIFUBSHFUTFSWFS )PXTPDLFUMJCSBSZTNFUIPETXPSL 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT D $POOFDUJPO0, 3FUVSOB4PDLFUPCKFDUDPOOFDUFEUPUIFUBSHFUTFSWFS

Slide 11

Slide 11 text

"UBSHFUTFSWFSNBZIBWFCPUI*1WBOE*1WBEESFTTFT *1WD *1W 4FSWFS $MJFOU 4FSWFS *TTVFTJO3VCZTTPDLFUMJCSBSZ

Slide 12

Slide 12 text

5IFSFGPSF BDMJFOUNVTURVFSZ%/4GPSCPUI*1WBOE *1WBEESFTTFT %/44FSWFS $MJFOU 5IF*1WBEESFTTJT D 5IF*1WBEESFTTJT "OTXFS*1WBEESFTTFT "OTXFS*1WBEESFTTFT *TTVFTJO3VCZTTPDLFUMJCSBSZ 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT

Slide 13

Slide 13 text

$VSSFOUMZ JURVFSJFTTFRVFOUJBMMZGPSFBDIBEESFTTGBNJMZ *U fi STURVFSJFTFJUIFSBO*1WPS*1WBEESFTT UIFORVFSJFTUIFPUIFSUZQFPODFBOTXFSFE %/44FSWFS $MJFOU *TTVFTJO3VCZTTPDLFUMJCSBSZ 2VFSZ*1WBEESFTTFTMBUFS 2VFSZ*1WBEESFTTFTFBSMJFS "OTXFS*1WBEESFTTFT FH

Slide 14

Slide 14 text

-FUTDPOTJEFSBTDFOBSJPXIFSF B%/4TFSWFSUBLFTBMPOHUJNFUPBOTXFSXJUI*1W BOEDBOBOTXFSJNNFEJBUFMZXJUI*1W *1WDBOOPUBOTXFSJNNFEJBUFMZ *1WDBOBOTXFS %/44FSWFS $MJFOU *TTVFTJO3VCZTTPDLFUMJCSBSZ

Slide 15

Slide 15 text

*TTVFTJO3VCZTTPDLFUMJCSBSZ *GBDMJFOURVFSJFTGPSUIF*1WBEESFTT fi STU JUFOETVQ XBJUJOHBMPOHUJNFGPSHFUUJOHUIFBOTXFS $BOOPUSFTQPOTFJNNFEJBUFMZ %FTQJUFUIFQPTTJCJMJUZPGBOJNNFEJBUF*1WBOTXFS %/44FSWFS $MJFOU *1WDBOOPUBOTXFSJNNFEJBUFMZ *1WDBOBOTXFS 2VFSZ*1WBEESFTTFT

Slide 16

Slide 16 text

'VSUIFSNPSF DPOTJEFSBTDFOBSJPXIFSFOBNFSFTPMVUJPO JTTVDDFTTGVMBOECPUI*1WBOE*1WBEESFTTFTBSF PCUBJOFE "DMJFOUBUUFNQUUPDPOOFDUUPPOFPGUIFSFTPMWFE*1 BEESFTT *1WSFTPMWFE *1WSFTPMWFE 4FSWFS $MJFOU 4FSWFS *TTVFTJO3VCZTTPDLFUMJCSBSZ 5PBSFTPMWFE*1BEESFTT

Slide 17

Slide 17 text

$VSSFOUMZ UIFBUUFNQUTBSFNBEFTFRVFOUJBMMZGPSFBDI*1 BEESFTT*GBDPOOFDUJPOBUUFNQUUPPOFBEESFTTGBJMT JUXBJUTVOUJMUIFGBJMVSFJTDPO fi SNFECFGPSFBUUFNQUJOH XJUIBOPUIFSBEESFTT 4FSWFS $MJFOU 4FSWFS *1WSFTPMWFE *1WSFTPMWFE *TTVFTJO3VCZTTPDLFUMJCSBSZ $POOFDUJPO0, 5PBOPUIFSSFTPMWFE*1BEESFTT $POOFDUJPO/050, 5PBSFTPMWFE*1BEESFTT

Slide 18

Slide 18 text

*TTVFTJO3VCZTTPDLFUMJCSBSZ /PXDPOTJEFSBHBJOBTDFOBSJPXIFSFBUBSHFUTFSWFS UBLFTBMPOHUJNFUPDPOOFDUXJUI*1WBOEDBODPOOFDU JNNFEJBUFMZXJUI*1W 4FSWFS $MJFOU 4FSWFS *1WDBOOPUDPOOFDUJNNFEJBUFMZ *1WDBODPOOFDU *1WSFTPMWFE *1WSFTPMWFE

Slide 19

Slide 19 text

*GBDMJFOUBUUFNQUTUPDPOOFDUUPBO*1WBEESFTT fi STU JUFOETVQXBJUJOHBMPOHUJNFGPSUIFDPOOFDUJPOUPCF FTUBCMJTIFE *TTVFTJO3VCZTTPDLFUMJCSBSZ $BOOPUSFTQPOTFJNNFEJBUFMZ 4FSWFS $MJFOU 4FSWFS %FTQJUFUIFDMJFOULOPXJOHBOBWBJMBCMF*1WBEESFTT *1WSFTPMWFE *1WSFTPMWFE 5PBSFTPMWFE*1WBEESFTT *1WDBOOPUDPOOFDUJNNFEJBUFMZ *1WDBODPOOFDU

Slide 20

Slide 20 text

5IFTFJTTVFTDPNNPOMZPDDVSJOFOWJSPONFOUT LOPXOBTEVBMTUBDL XIFSFBUBSHFUTFSWFSIBWF CPUI*1WBOE*1WBEESFTTFT

Slide 21

Slide 21 text

5PBEESFTTUIJT *&5'IBTTQFDJ fi FEBOBMHPSJUIN JO3'$UPSFEVDFUIJTQSPCMFN 5IBUJT

Slide 22

Slide 22 text

)BQQZ&ZFCBMMT7FSTJPO IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGD

Slide 23

Slide 23 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT /PX MFUTTFFIPX)&WXPSLT"DDPSEJOHUP3'$ UIJTBMHPSJUINJODMVEFTGPVSQIBTFT )BQQZ&ZFCBMMT7FSTJPO#FUUFS$POOFDUJWJUZ6TJOH$PODVSSFODZ0WFSWJFX IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGDTFDUJPO

Slide 24

Slide 24 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT /PX MFUTTFFIPX)&WXPSLT"DDPSEJOHUP3'$ UIJTBMHPSJUINJODMVEFTGPVSQIBTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT )BQQZ&ZFCBMMT7FSTJPO#FUUFS$POOFDUJWJUZ6TJOH$PODVSSFODZ0WFSWJFX IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGDTFDUJPO

Slide 25

Slide 25 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT /PX MFUTTFFIPX)&WXPSLT"DDPSEJOHUP3'$ UIJTBMHPSJUINJODMVEFTGPVSQIBTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 4PSUJOHPGSFTPMWFEEFTUJOBUJPOBEESFTTFT )BQQZ&ZFCBMMT7FSTJPO#FUUFS$POOFDUJWJUZ6TJOH$PODVSSFODZ0WFSWJFX IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGDTFDUJPO

Slide 26

Slide 26 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT /PX MFUTTFFIPX)&WXPSLT"DDPSEJOHUP3'$ UIJTBMHPSJUINJODMVEFTGPVSQIBTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 4PSUJOHPGSFTPMWFEEFTUJOBUJPOBEESFTTFT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT )BQQZ&ZFCBMMT7FSTJPO#FUUFS$POOFDUJWJUZ6TJOH$PODVSSFODZ0WFSWJFX IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGDTFDUJPO

Slide 27

Slide 27 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT /PX MFUTTFFIPX)&WXPSLT"DDPSEJOHUP3'$ UIJTBMHPSJUINJODMVEFTGPVSQIBTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 4PSUJOHPGSFTPMWFEEFTUJOBUJPOBEESFTTFT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT &TUBCMJTINFOUPGPOFDPOOFDUJPO XIJDIDBODFMT BMMPUIFSBUUFNQUT )BQQZ&ZFCBMMT7FSTJPO#FUUFS$POOFDUJWJUZ6TJOH$PODVSSFODZ0WFSWJFX IUUQTEBUBUSBDLFSJFUGPSHEPDIUNMSGDTFDUJPO

Slide 28

Slide 28 text

)PX)BQQZ&ZFCBMMT7FSTJPO )&W XPSLT -FUTMPPLBUUIJTJOBMJUUMFNPSFEFUBJM 5IFNBJODPNQPOFOUTBSFUIFTBNFBTCFGPSF BDMJFOU B%/4TFSWFS BOEBUBSHFUTFSWFS %/44FSWFS 4FSWFS $MJFOU 4FSWFS

Slide 29

Slide 29 text

*OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 5IF fi STUQIBTFJTBTZODISPOPVT%/4RVFSJFT "DMJFOURVFSJFTGPSBO*1WBEESFTT fi STU UIFO JNNFEJBUFMZGPS*1WXJUIPVUXBJUJOHGPSUIF*1WBOTXFS %/44FSWFS 4FSWFS $MJFOU 4FSWFS 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT 2VFSZBUBCPVUUIFTBNFUJNF

Slide 30

Slide 30 text

*G*1WBEESFTTFTBSFSFTPMWFE fi STU %/44FSWFS 4FSWFS $MJFOU 4FSWFS "OTXFS*1WBEESFTTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT

Slide 31

Slide 31 text

UIFDMJFOUJNNFEJBUFMZTUBSUTUPDPOOFDUUPPOFPGUIF *1WBEESFTTFT %/44FSWFS 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1WBEESFTT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT "OTXFS*1WBEESFTTFT

Slide 32

Slide 32 text

*G*1WBEESFTTFTBSFSFTPMWFECFGPSF*1WBEESFTTFT %/44FSWFS 4FSWFS $MJFOU 4FSWFS "OTXFS*1WBEESFTTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT 2VFSZ*1WBEESFTTFT 2VFSZ*1WBEESFTTFT

Slide 33

Slide 33 text

XBJUGPSNTGPS*1WBEESFTTFTUPCFSFTPMWFE 5IJTJTCFDBVTF 3'$TQFDJ fi FTUIBU)&WQSFGFSTUP DPOOFDUXJUI*1WJGQPTTJCMF %/44FSWFS 4FSWFS $MJFOU 4FSWFS "OTXFS*1WBEESFTTFT 8BJUNTGPS*1WBOTXFS /P*1WBOTXFST *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT

Slide 34

Slide 34 text

*G*1WBEESFTTFTBSFSFTPMWFEXJUIJOUIJTUJNF JUTUBSUTBDPOOFDUJPOBUUFNQUUPPOFPGUIFN JNNFEJBUFMZ %/44FSWFS 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1WBEESFTT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT "OTXFS*1WBEESFTTFT "OTXFS*1WBEESFTTFT

Slide 35

Slide 35 text

*G*1WBEESFTTFTDBOOPUCFSFTPMWFEXJUIJONT BDPOOFDUJPOBUUFNQUJTTUBSUFEUPPOFPGUIFSFTPMWFE *1WBEESFTTFT *OJUJBUJPOPGBTZODISPOPVT%/4RVFSJFT %/44FSWFS 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1WBEESFTT /P*1WBOTXFST "OTXFS*1WBEESFTTFT

Slide 36

Slide 36 text

8IFORVFSZJOHBEPNBJOOBNFPGBUBSHFUTFSWFS JUJT PGUFOUIFDBTFUIBUNVMUJQMF*1WBOE*1WBEESFTTFTBSF PCUBJOFE 4PSUJOHPGSFTPMWFEEFTUJOBUJPOBEESFTTFT %/44FSWFS $MJFOU "OTXFS*1WBEESFTTFT "OTXFS*1WBEESFTTFT *1WBEESFTTFTBSF D D *1WBEESFTTFTBSF 2VFSJFT*1WBEESFTT 2VFSJFT*1WBEESFTT

Slide 37

Slide 37 text

*OTVDIBDBTF UIFDMJFOUTPSUTUIFBEESFTTFTBDDPSEJOH UP3'$BOE4FDUJPOPG3'$ BMMPXJOHDPOOFDUJPOBUUFNQUTUPCFTUBSUFEGSPNUIF QSFGFSSFEBEESFTT $MJFOU D D 4PSUJOHPGSFTPMWFEEFTUJOBUJPOBEESFTTFT

Slide 38

Slide 38 text

"GUFSTUBSUJOHBDPOOFDUJPOBUUFNQU TPNFUJNFTUIFDPOOFDUJPOJTFTUBCMJTIFEJNNFEJBUFMZ BOETPNFUJNFTJUJTOPU *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT $BOUIFDPOOFDUJPOCFFTUBCMJTIFEJNNFEJBUFMZ

Slide 39

Slide 39 text

5IFDMJFOUXBJUTNTGSPNUIFTUBSUPGUIFDPOOFDUJPO GPSJUUPCFFTUBCMJTIFE *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT 8BJUGPSNT

Slide 40

Slide 40 text

*GUIFDPOOFDUJPOJTOUFTUBCMJTIFEXJUIJOUIBUUJNF UIFDMJFOUPCUBJOTBOPUIFSBEESFTTGSPNUIFMJTUPG SFTPMWFE*1BEESFTTFTUIBUIBTOPUZFUCFFOBUUFNQUFE *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT 6OBUUFNQUFEBEESFTTFT 0CUBJO

Slide 41

Slide 41 text

*UUIFOTUBSUTBOFXDPOOFDUJPOBUUFNQUUPUIFPCUBJOFE BEESFTT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT 4FSWFS $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT

Slide 42

Slide 42 text

'SPNUIJTQPJOUPOXBSET BTMPOHBTUIFSFBSFBEESFTTFT UIBUIBWFOUCFFOBUUFNQUFE UIFGPMMPXJOHTUFQTXJMMCF SFQFBUFEFWFSZNT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT 8BJUGPSNT

Slide 43

Slide 43 text

0CUBJOJOHBOBEESFTTGSPNUIFMJTUPGSFTPMWFE*1 BEESFTTFT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS 6OBUUFNQUFEBEESFTTFT 0CUBJO 5PBSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT

Slide 44

Slide 44 text

4UBSUJOHBDPOOFDUJPOBUUFNQUUPUIFPCUBJOFEBEESFTT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS 6OBUUFNQUFEBEESFTTFT 0CUBJO 5PBSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT

Slide 45

Slide 45 text

8BJUJOHGPSPOFPGUIFDPOOFDUJPOTUPCFFTUBCMJTIFEGPS NT "OEUIJTJTUIFUIJSEQIBTF *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS 6OBUUFNQUFEBEESFTTFT 0CUBJO 5PBSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT 8BJUGPSNT

Slide 46

Slide 46 text

"EEJUJPOBMMZ JOTPNFDBTFT OBNFSFTPMVUJPOGPSPUIFS BEESFTTGBNJMZFOETJOUIFCBDLHSPVOEEVSJOHSFQFBUFE DPOOFDUJPOBUUFNQUT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS 5PBSFTPMWFE*1BEESFTT %/44FSWFS "OTXFSPUIFSBEESFTTFT

Slide 47

Slide 47 text

*OUIJTDBTF UIFOFXMZPCUBJOFEBEESFTTFTBSFBEEFEUP UIFMJTUPGSFTPMWFE*1BEESFTTFTBOEVTFEGPS TVCTFRVFOUDPOOFDUJPOBUUFNQUT *OJUJBUJPOPGBTZODISPOPVTDPOOFDUJPOBUUFNQUT $MJFOU 4FSWFS "EEPUIFSSFTPMWFEBEESFTTFT 6OBUUFNQUFEBEESFTTFT 5PBSFTPMWFE*1BEESFTT

Slide 48

Slide 48 text

0ODFBDPOOFDUJPOJTTVDDFTTGVMMZFTUBCMJTIFE UIFDMJFOU BOEUIFUBSHFUTFSWFSDPNNVOJDBUFWJBUIBU*1BEESFTT &TUBCMJTINFOUPGPOFDPOOFDUJPO XIJDIDBODFMTBMMPUIFSBUUFNQUT $MJFOU 4FSWFS $POOFDUJPO0,XJUIUIFBEESFTT C 5IFSFBGUFS DPNNVOJDBUFWJBUIFBEESFTT C NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT C 5PBSFTPMWFE*1BEESFTT B

Slide 49

Slide 49 text

"UUIJTQPJOU UIFDMJFOUDBODFMTPUIFSDPOOFDUJPO BUUFNQUT5IJTJTUIFGPVSUIQIBTF $MJFOU 4FSWFS $BODFM &TUBCMJTINFOUPGPOFDPOOFDUJPO XIJDIDBODFMTBMMPUIFSBUUFNQUT $POOFDUJPO0,XJUIUIFBEESFTT C NTMBUFS UPBOPUIFSSFTPMWFE*1BEESFTT C 5PBSFTPMWFE*1BEESFTT B

Slide 50

Slide 50 text

*UTFFNTTJNQMF

Slide 51

Slide 51 text

"OZXBZ MFUTDPOTJEFSJNQMFNFOUJOH )BQQZ&ZFCBMMT7FSTJPOJO3VCZTPDLFUMJCSBSZ

Slide 52

Slide 52 text

5IFNFUIPETUBSHFUFEGPSUIFJOUSPEVDUJPOPG )&WBSF 4PDLFUUDQ JNQMFNFOUFECZ3VCZ 5$14PDLFUOFX JNQMFNFOUFECZ$ 5IJTUJNF *EMJLFUPGPDVTPO4PDLFUUDQ

Slide 53

Slide 53 text

class Socket def self.tcp(host, port) # Do something end end /PX MFUTJNQMFNFOU4PDLFUUDQUIBUTVQQPSUT)&W *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 54

Slide 54 text

class Socket def self.tcp(host, port) threads = [Socket::AF_INET6, Socket::AF_INET].map { |family| Thread.new(...) { |...| addresses = Addrinfo.getaddrinfo(...) shared_list.concat(addresses); cond.signal } } connected_socket = loop do cond.wait(mutex) while addresses.empty? address = addresses.shift; socket = Socket.new(...) socket.connect_nonblock(address); sockets.push(socket) _, writables, = IO.select(nil, sockets, nil, 0.25) connected_socket = pick_connected_socket(...) break connected_socket if connected_socket end connected_socket end end "OEJUJTDPNQMFUFE *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 55

Slide 55 text

class Socket def self.tcp(host, port) # ... threads = [Socket::AF_INET6, Socket::AF_INET].map { |family| args = { Thread.new(args) { |args| addresses = Addrinfo.getaddrinfo(...) sleep 0.05 if addresses.last == Socket::AF_INET args[:mutex].synchronize do args[:shared_list].concat(addresses) args[:cond].signal end } } # ... end end 5IF fi STUQBSUJTUPIBOEMFOBNFSFTPMVUJPO *UTUBSUTCZDSFBUJOHUISFBETGPSFBDIBEESFTTGBNJMZ BOETUBSUIPTUOBNFSFTPMVUJPOBTZODISPOPVTMZ XJUIJOFBDIUISFBE )PTUOBNFSFTPMVUJPO $SFBUFBUISFBE *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W { host:, port:, family:, resolved_addresses:, mutex:, cond: }

Slide 56

Slide 56 text

class Socket def self.tcp(host, port) # ... threads = [Socket::AF_INET6, Socket::AF_INET].map { |family| args = { Thread.new(args) { |args| addresses = Addrinfo.getaddrinfo(...) sleep 0.05 if addresses.last == Socket::AF_INET args[:mutex].synchronize do args[:resolved_addresses].concat(addresses) args[:cond].signal end } } # ... end end 0ODFOBNFSFTPMVUJPOJT fi OJTIFE BEEUIFOFXBEESFTTFTUPUIFMJTUPGSFTPMWFE *1BEESFTTFT "EEBEESFTTFTUPUIFMJTU *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W { host:, port:, family:, resolved_addresses:, mutex:, cond: }

Slide 57

Slide 57 text

class Socket def self.tcp(host, port) # ... threads = [Socket::AF_INET6, Socket::AF_INET].map { |family| # ... } # Do "obtaining an address", "starting a connection attempt", # and "waiting for connections" # ... end end 5IFOFYUQBSUJTDPOOFDUJPOQSPDFTTJOH 5IFQSPDFTTPGPCUBJOJOHBOBEESFTT TUBSUJOHB DPOOFDUJPOBUUFNQUBOEXBJUJOHGPSDPOOFDUJPOTJT SFQFBUFEFWFSZNT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 58

Slide 58 text

class Socket def self.tcp(host, port) # ... threads = [Socket::AF_INET6, Socket::AF_INET].map { |family| # ... } loop do # Do "obtaining an address", "starting a connection # and "waiting for connections" end # ... end end 6TF,FSOFMMPPQUPSFQFBUUIFTFTUFQT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W n attempt",

Slide 59

Slide 59 text

class Socket def self.tcp(host, port) # ... loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = Socket.new(...) # ... end # ... end end 6QPO fi STUFOUFSJOHUIFMPPQ UIFMJTUPGSFTPMWFE*1 BEESFTTFTJTFNQUZ8BJUVOUJMBOZDIJMEUISFBEBEET BEESFTTFT UIFOCSFBLUIFXBJUBOEPCUBJOPOFPGUIFN 8BJUGPSBEESFTTFT 0CUBJOBOBEESFTT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 60

Slide 60 text

class Socket def self.tcp(host, port) # ... loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) # ... end # ... end end 5IFOTUBSUBDPOOFDUJPOBUUFNQU UPUIFPCUBJOFEBEESFTT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W 4UBSUBDPOOFDUJPOBUUFNQU

Slide 61

Slide 61 text

class Socket def self.tcp(host, port) # ... loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # cleanup connected end end "GUFSTUBSUJOHUIFDPOOFDUJPO XBJUGPSNT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W 8BJUGPSDPOOFDUJPOT

Slide 62

Slide 62 text

class Socket def self.tcp(host, port) # ... loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end do_cleanup connected end end *GBDPOOFDUJPOJTFTUBCMJTIFEXJUIJOUIFUJNF FYJUUIF MPPQ"GUFSQPTUQSPDFTTJOH SFUVSOUIFDPOOFDUFE TPDLFU BOEUIFNFUIPEDPODMVEFT 0CUBJODPOOFDUFETPDLFU 3FUVSOJU *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 63

Slide 63 text

class Socket def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end do_cleanup connected end end 0UIFSXJTF JUHPFTUPUIFUPQPGUIFMPPQBOESFQFBUT UIFQSPDFTTPGPCUBJOJOHBOBEESFTT TUBSUJOH BDPOOFDUJPOBUUFNQU BOEXBJUJOHGPSDPOOFDUJPOT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W &OUFSUIFOFYUMPPQ

Slide 64

Slide 64 text

class Socket def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end do_cleanup connected end end 4PDLFUUDQXJUI)&WTVQQPSUFEJTOPXDPNQMFUF *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 65

Slide 65 text

)PXFWFS

Slide 66

Slide 66 text

"DUVBMMZ XIBUZPVWFTFFOTPGBSJT BTJNQMJ fi FEWFSTJPOPGNZJOJUJBMJNQMFNFOUBUJPO XIFO*TUBSUFEXPSLJOHPO)&W 5IJTJNQMFNFOUBUJPOIBETPNFJTTVFT 'PSFYBNQMF *TTVFTXJUIUIJTJNQMFNFOUBUJPO

Slide 67

Slide 67 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end *TTVFTXJUIUIJTJNQMFNFOUBUJPO -FUTDPOTJEFSUIFDBTFXIFSF BGUFSTUBSUJOHB DPOOFDUJPOBUUFNQU JUIBTOPUCFFOFTUBCMJTIFE XJUIJONT BOEJUFOUFSTUIFOFYUMPPQ &OUFSUIFOFYUMPPQ

Slide 68

Slide 68 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end 4VQQPTFUIFMJTUPGSFTPMWFE*1BEESFTTFTJTFNQUZ BUUIJTUJNF *GTP JUXJMMXBJUIFSFVOUJMOFXBEESFTTFTBSFBEEFE 8BJUIFSF *TTVFTXJUIUIJTJNQMFNFOUBUJPO &NQUZ

Slide 69

Slide 69 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end 8IBUTIPVMEJUEPJGUIFDPOOFDUJPOJTFTUBCMJTIFEJO UIFCBDLHSPVOEEVSJOHUIJTUJNF "DPOOFDUJPOJTFTUBCMJTIFE JOUIFCBDLHSPVOE *TTVFTXJUIUIJTJNQMFNFOUBUJPO 8BJUIFSF &NQUZ

Slide 70

Slide 70 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end *OTVDIBDBTF UIFNFUIPETIPVMESFUVSOUIFDPOOFDUFE TPDLFUJNNFEJBUFMZ)PXFWFS JUTJNQPTTJCMFUPEFUFDUB FTUBCMJTIFEDPOOFDUJPOXIJMFBXBJUJOHBEESFTTFTDVSSFOUMZ *TTVFTXJUIUIJTJNQMFNFOUBUJPO $BOUTUPQUPXBJU &NQUZ

Slide 71

Slide 71 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end 0SXIBUXPVMEIBQQFOJGUIFMJTUPGSFTPMWFE*1 BEESFTTFTJTFNQUZBOEBMMBEESFTTGBNJMJFTIBWFCFFO OBNFSFTPMWFE *TTVFTXJUIUIJTJNQMFNFOUBUJPO 8BJUIFSF &NQUZ "MMOBNFSFTPMVUJPOTIBWF BMSFBEZCFFO fi OJTIFE

Slide 72

Slide 72 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end *OTVDIBDBTF OPOFXBEESFTTFTXJMMCFBEEFEUP UIFMJTU BOEUIVT UIFQSPDFTTXPVMECFQFSNBOFOUMZ TUPQQFE *TTVFTXJUIUIJTJNQMFNFOUBUJPO 8BJUIFSFGPSFWFS &NQUZ

Slide 73

Slide 73 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end "MTP DPOOFDUJPOBUUFNQUTDBOGBJMXJUIJONTPGTUBSUJOH *OTVDIBDBTF JUTIPVMEXBJUGPSUIFSFNBJOEFSPGUIFNT CFGPSFFOUFSJOHUIFOFYUMPPQBOETUBSUBOFXBUUFNQU *UUVSOFEPVUUIBUBDPOOFDUJPOBUUFNQUJTGBJMFE *TTVFTXJUIUIJTJNQMFNFOUBUJPO

Slide 74

Slide 74 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) break connected if connected end # ... end #VUXJUIUIFJNQMFNFOUBUJPO JUQSPDFFETUPUIFOFYU MPPQXJUIPVUXBJUJOHGPSUIFSFNBJOEFSPGUIFUJNF JNNFEJBUFMZTUBSUJOHBOFXDPOOFDUJPOBUUFNQU &OUFSUIFOFYUMPPQXJUIPVU XBJUJOHGPSSFNBJOJOHUJNF *TTVFTXJUIUIJTJNQMFNFOUBUJPO 4UBSUBOFXDPOOFDUJPOBUUFNQU

Slide 75

Slide 75 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end 5PBWPJEUIJT TIPVMEJUTMFFQGPSUIFSFNBJOJOHUJNF JGBOZDPOOFDUJPOTGBJM 4IPVMETMFFQ *TTVFTXJUIUIJTJNQMFNFOUBUJPO

Slide 76

Slide 76 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end *OUIBUDBTF JGPUIFSDPOOFDUJPOTBSFJOQSPHSFTTBOE POFJTFTUBCMJTIFEXIJMFTMFFQJOHJOUIFCBDLHSPVOE JUDBOUEFUFDUUIFFTUBCMJTIFEDPOOFDUJPO $BOUEFUFDUFTUBCMJTIFEDPOOFDUJPOT *TTVFTXJUIUIJTJNQMFNFOUBUJPO "DPOOFDUJPOJTFTUBCMJTIFE JOUIFCBDLHSPVOE

Slide 77

Slide 77 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end 0S JGUIFMJTUPGSFTPMWFE*1BEESFTTFTJTFNQUZJOUIF OFYUMPPQBGUFSXBLJOHGSPNTMFFQ JUXPVMETUBSUXBJUJOH GPSBEESFTTFTBHBJO"OETPPOBOETPGPSUI &OUFSUIFOFYUMPPQ *TTVFTXJUIUIJTJNQMFNFOUBUJPO 4UBSUUPXBJUIFSFBHBJO JGUIFMJTUJTFNQUZ &NQUZ

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

8IZEPFTUIFNIBQQFO def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end -FUTSFWJTJUUIFDVSSFOUJNQMFNFOUBUJPO UPDMBSJGZUIFVOEFSMZJOHQSPCMFN

Slide 80

Slide 80 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end 8JUIJOUIJTMPPQ GSPNUIFUPQEPXO JUTXBJUJOHGPS OBNFSFTPMVUJPOTBOEPCUBJOJOHBOBEESFTT 8IZEPFTUIFNIBQQFO 8BJUGPSOBNFSFTPMVUJPOT "DPOUJOVPVTTFRVFODFJOUIFMPPQ 0CUBJOBOBEESFTT

Slide 81

Slide 81 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end TUBSUJOHBDPOOFDUJPOBUUFNQU 8IZEPFTUIFNIBQQFO "DPOUJOVPVTTFRVFODFJOUIFMPPQ 4UBSUBDPOOFDUJPOBUUFNQU

Slide 82

Slide 82 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end BOEXBJUJOHGPSUIPTFDPOOFDUJPOT BTBDPOUJOVPVTTFRVFODF 8IZEPFTUIFNIBQQFO 8BJUGPSDPOOFDUJPOT "DPOUJOVPVTTFRVFODFJOUIFMPPQ

Slide 83

Slide 83 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end 8IZEPFTUIFNIBQQFO )PXFWFS EFQFOEJOHPOUIFTUBUVTPGUIFMJTUPG SFTPMWFE*1BEESFTTFTBOEUIFDPOOFDUJOHTPDLFUT VOOFDFTTBSZEFMBZTDBOPDDVSXJUIJOUIFMPPQ 6OOFDFTTBSZEFMBZTDBOPDDVS "DPOUJOVPVTTFRVFODFJOUIFMPPQ

Slide 84

Slide 84 text

def self.tcp(host, port) # ... connected = loop do mutex.synchronize do cond.wait(mutex) while resolved_addresses.empty? address = resolved_addresses.shift end socket = sockets.push(Socket.new(...)).last socket.connect_nonblock(address, exception: false) _, writable_sockets, = IO.select(nil, sockets, nil, 0.25) connected = pick_connected_socket(writable_sockets, sockets) sleep(remaining) if connection_failed break connected if connected end # ... end 8IZEPFTUIFNIBQQFO 5IFQSPDFTTUIBUTIPVMECFFYFDVUFEJOUIFMPPQTFFNT UPCFEJ ff FSFOUFBDIUJNF EFQFOEJOHPOUIFTUBUVT PGUIFMJTUPGBEESFTTFTBOEUIFDPOOFDUJOHTPDLFUT "DPOUJOVPVTTFRVFODFJOUIFMPPQ

Slide 85

Slide 85 text

5IFOBUVSFPG)&W 5PQVUJUNPSFBCTUSBDUMZ JUHPFTMJLFUIJT )&WBMHPSJUINEFBMTXJUISFTPVSDFTTVDIBTSFTPMWFE*1 BEESFTTFTBOEDPOOFDUJOHTPDLFUT $POOFDUJOHTPDLFUT 3FTPVSDFT 3FTPMWFE*1BEESFTTFT

Slide 86

Slide 86 text

"QQSPQSJBUFBDUJPOTBSFFYFDVUFECBTFEPOUIFTF SFTPVSDFT 5IFOBUVSFPG)&W $POOFDUJOHTPDLFUT 3FTPVSDFT 3FTPMWFE*1BEESFTTFT 3FTPMWFIPTUOBNF "DUJPO

Slide 87

Slide 87 text

"TBSFTVMU UIFSFTPVSDFTBSFDIBOHFE 5IFOBUVSFPG)&W $POOFDUJOHTPDLFUT 3FTPVSDFT 3FTPMWFE*1BEESFTTFT 3FTPMWFE*1BEESFTTFTBSFBEEFE

Slide 88

Slide 88 text

5IFOFYUBDUJPOTBSFFYFDVUFECBTFEPOUIFDIBOHFE SFTPVSDFT5IFOUIFSFTPVSDFTBSFDIBOHFEBHBJO 5IFOBUVSFPG)&W $POOFDUJOHTPDLFUT 3FTPVSDFT 3FTPMWFE*1BEESFTTFT 4UBSUUPDPOOFDU "DUJPO "$POOFDUJOHTPDLFUJTBEEFE

Slide 89

Slide 89 text

5IFOFYUBDUJPOTBSFFYFDVUFECBTFEPOUIFDIBOHFE TUBUFPGUIFSFTPVSDFT5IFOUIFTUBUFPGUIFSFTPVSDF DIBOHFTBHBJO 5IFOBUVSFPG)&W $POOFDUJOHTPDLFUT 3FTPVSDFT 3FTPMWFE*1BEESFTTFT "$POOFDUJOHTPDLFUJTBEEFE 4UBSUUPDPOOFDU "DUJPO 5IJTDPVMENFBO JUTFTTFOUJBMMZBTUBUFNBDIJOF DPVMEO`UJU

Slide 90

Slide 90 text

"DUVBMMZ UIFTUBUFUSBOTJUJPOEJBHSBNPGUIJTIBEBMSFBEZCFFO DSFBUFECZ!BLSEVSJOHUIF3VCZ"TTPDJBUJPOHSBOU ɹ )&WTTUBUFUSBOTJUJPO IUUQTXXXSVCZPSKQHSBOUNBUTVTIJUB@NFOUPS@SFQPSUQEG

Slide 91

Slide 91 text

)&WTTUBUFUSBOTJUJPO 4P JOUIFBDUVBMEFWFMPQNFOUUIJTUJNF UPVOEFSTUBOEUIF fl PXPG)&W`TCFIBWJPS *TUBSUFECZDSFBUJOHQTFVEPDPEF MJLFUIJT SFGFSSJOHUIFFBSMJFSEJBHSBNBTBIJOU case start to - v6c - v4w - failure - timeout do Thread.new { IPv6 Addrinfo.getaddrinfo } Thread.new { IPv4 Addrinfo.getaddrinfo } Until the next state is determined select([Hostname resolution rpipe], Resolv timeout expires at) case IPv6 resolved Selectable addrinfo = Hostname resolution queue.pop Selectable addrinfos.push Selectable addrinfo -> v6c "OFYBNQMFPGUIFQTFVEPDPEF

Slide 92

Slide 92 text

)&WTTUBUFUSBOTJUJPO 5PDPNQMFUFUIJT JUTOFDFTTBSZUPDPOTJEFSUIFTUBUFTSFRVJSFEGPS JNQMFNFOUBUJPOBOEUPDPWFSQPUFOUJBMDPSOFSDBTFT "TBSFTVMU XIBUJUFOEFEVQXJUI

Slide 93

Slide 93 text

)&WTTUBUFUSBOTJUJPO case start to - v6c - v4w - failure - timeout do Local addrinfos = Addrinfo.getaddrinfo case ϦϞʔτϗετ·ͨ͸ϩʔΧϧϗετ͕IPΞυϨε addrinfo = Addrinfo.getaddrinfo Selectable addrinfos.push Selectable addrinfo case IPv6 addrinfo -> v6c case IPv4 addrinfo -> v4c case ϦϞʔτϗετͱϩʔΧϧϗετ͕υϝΠϯ໊ Thread.new { IPv6 Addrinfo.getaddrinfo } Thread.new { IPv4 Addrinfo.getaddrinfo } while ࣍ͷstate͕ܾఆ͢Δ·Ͱ select([Hostname resolution rpipe], Resolv timeout expires at) case Resolv timeout expires at ௒ա -> timeout case v6໊લղܾ Selectable addrinfo = Hostname resolution queue.pop Selectable addrinfos.push Selectable addrinfo -> v6c case v4໊લղܾ Selectable addrinfo = Hostname resolution queue.pop Selectable addrinfos.push Selectable addrinfo -> v4w case ໊લղܾΤϥʔ case retryable: true retry case retryable: false Last error = Τϥʔ -> failure case v4w from - start condition - selectͷฦΓ஋: - Resolution delay expires at ௒ա - v6໊લղܾ - ໊લղܾΤϥʔ to - v4c - v46c do select([Hostname resolution rpipe], Resolution delay expires at) case Resolution delay expires at ௒ա -> v4c case v6ΞυϨεղܾ Selectable addrinfo = Hostname resolution queue.pop Selectable addrinfos.push Selectable addrinfo -> v46c case ໊લղܾΤϥʔ -> v46c case v6c, v4c, v46c from - start - v4w - v46w to - v46c - v46w - success - failure do Connecting addrinfo = Selectable addrinfos.pop Connecting socket = Socket.new(Connecting addrinfo) case Local addrinfos: any case Connecting addrinfoͱಉ͡ΞυϨεϑΝϛϦͷLocal addrinfo͕͋Δ Local addrinfo = Local addrinfos.pick Connecting socket.bind Local addrinfo ҎԼ΁ਐΉ case Connecting addrinfoͱಉ͡ΞυϨεϑΝϛϦͷLocal addrinfo͕ͳ͍ case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: closed # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened # ࣍ͷϧʔϓͰ઀ଓ໊͔લղܾΛ଴ͭ # Connecting sockets͕͋Δ͏ͪ͸Resolv timeout expires at ͸ߟྀ͠ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed # ࣍ͷϧʔϓͰ઀ଓΛ଴ͭ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened case Resolv timeout expires at: ઃఆ͋Γ && Resolv timeout expires at ௒ա -> timeout case ͦΕҎ֎ # ࣍ͷϧʔϓͰ໊લղܾΛ଴ͭ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed -> failure case Local addrinfos: empty ҎԼ΁ਐΉ Connection attempt delay expires at = ݱࡏͷΫϩοΫ࣌ؒ + Connection Attempt Delay case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed connect case ͦΕҎ֎ connect_nonblock ҎԼ΁ਐΉ case ઀ଓʹ੒ޭ -> success case ઀ଓத Connecting sockets.add Connecting socket -> v46w case SystemCallError Last error = SystemCallError case Selectable addrinfos: any && Connecting Sockets: any && Hostname resolution queue: opened # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting Sockets: any && Hostname resolution queue: closed # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting Sockets: empty && Hostname resolution queue: opened # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: any && Connecting Sockets: empty && Hostname resolution queue: closed # ࣍ͷϧʔϓͰผͷSelectable addrinfoΛࢼ͢ -> v46c case Selectable addrinfos: empty && Connecting Sockets: any && Hostname resolution queue: opened # ࣍ͷϧʔϓͰ໊લղܾ͔઀ଓΛ଴ͭɻ໊લղܾͨ͠৔߹͸͞Βʹ࣍ͷϧʔϓͰv46c΁ɺ઀ଓͨ͠৔߹͸͞Βʹ࣍ͷϧʔϓͰsuccess΁ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting Sockets: any && Hostname resolution queue: closed # ࣍ͷϧʔϓͰ઀ଓΛ଴ͭ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting Sockets: empty && Hostname resolution queue: opened case Resolv timeout expires at: ઃఆ͋Γ && Resolv timeout expires at ௒ա -> timeout case ͦΕҎ֎ # ࣍ͷϧʔϓͰ໊લղܾΛ଴ͭ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting Sockets: empty && Hostname resolution queue: closed -> failure case v46w from - v6c - v4c - v46c - v46w to - v46c - v46w - success - timeout do case Connect timeout expires at ௒ա -> timeoeut case Connect timeout expires at ௒աͰ͸ͳ͍ ҎԼ΁ਐΉ select([Hostname resolution rpipe], Connecting sockets, Connection attempt delay expires at) case Connectable sockets: any while (Connectable socket = Connectable sockets.pop) Connecting sockets.remove Connectable socket getsockopt(<઀ଓΤϥʔͷ֬ೝ>) case Τϥʔͳ͠ Connected socket = Connectable socket -> success case Τϥʔ͋Γ case Connectable sockets: any retry case Connectable sockets: empty ҎԼʹਐΉ case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ઀ଓ໊͔લղܾΛ଴ͭ # ઀ଓ͠ͳ͔ͬͨ৔߹ɺ໊લղܾͯ͠΋͠ͳͯ͘΋͞Βʹ࣍ͷϧʔϓͰv46c΁ -> v46w case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: closed # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ઀ଓΛ଴ͭ # ઀ଓ͠ͳ͔ͬͨ৔߹͸͞Βʹ࣍ͷϧʔϓͰv46c΁ -> v46w case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ໊લղܾΛ଴ͭ # ໊લղܾͯ͠΋͠ͳͯ͘΋͞Βʹ࣍ͷϧʔϓͰv46c΁ -> v46w case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ໊લղܾΛ଴ͭ # ͞Βʹ࣍ͷϧʔϓͰv46c΁ -> v46w case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened # ͋ͱ͸઀ଓ໊͔લղܾΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ # Connecting sockets͕͋Δ͏ͪ͸Resolv timeout expires at ͸ߟྀ͠ͳ͍ -> v46w case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed # ͋ͱ͸઀ଓΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened case Resolv timeout expires at: ઃఆ͋Γ && Resolv timeout expires at ௒ա -> timeout case ͦΕҎ֎ # ͋ͱ͸໊લղܾΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed -> failure case ໊લղܾ Selectable addrinfo = Hostname resolution queue.pop Selectable addrinfos.push Selectable addrinfo # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ଴ͪɺ͞Βʹ࣍ͷϧʔϓͰv46c΁ -> v46w case ໊લղܾΤϥʔ # ࣍ͷϧʔϓͰConnection attempt delay expires atΛ௒ա͢Δ·Ͱ଴ͪɺ͞Βʹ࣍ͷϧʔϓͰϦιʔεͷঢ়ଶʹΑͬͯ෼ذ -> v46w case Connection attempt delay expires at ௒ա case Selectable addrinfos: any && Connecting sockets: any && Hostname resolution queue: opened -> v46c case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened -> v46c case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: opened -> v46c case Selectable addrinfos: any && Connecting sockets: empty && Hostname resolution queue: closed -> v46c case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: opened # ͋ͱ͸઀ଓ໊͔લղܾΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ # Connecting sockets͕͋Δ͏ͪ͸Resolv timeout expires at ͸ߟྀ͠ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: opened case Resolv timeout expires at: ઃఆ͋Γ && Resolv timeout expires at ௒ա -> timeout case ͦΕҎ֎ # ͋ͱ͸໊લղܾΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: any && Hostname resolution queue: closed # ͋ͱ͸઀ଓΛͻͨ͢Β଴ͭ͜ͱ͔͠Ͱ͖ͳ͍ Connection attempt delay expires at = nil -> v46w case Selectable addrinfos: empty && Connecting sockets: empty && Hostname resolution queue: closed -> failure case success from - v46w do cleanup return Connected socket case failure from - start do cleanup raise Last error case timeout from - start do cleanup raise Errno::ETIMEDOUT, 'user specified timeout' UVSOFEPVUMJLFUIJT 8SJUUFOJO+BQBOFTF 5IFBDUVBMQTFVEPDPEFDSFBUFE

Slide 94

Slide 94 text

)&WTTUBUFUSBOTJUJPO "OZXBZ IBWJOHJEFOUJ fi FEUIFOFDFTTBSZTUBUFTUP JNQMFNFOU)&W *XJMMJOUSPEVDFUIFCBTJDCFIBWJPSTPG )&WBMPOHXJUIUIFN

Slide 95

Slide 95 text

)&WTTUBUFUSBOTJUJPOTUBSU $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ &NQUZ "UUIFTUBSU UIFSFBSFUXPUZQFTPGFNQUZSFTPVSDFT 0OFJTUIFMJTUPGSFTPMWFE*1BEESFTTFT BOEUIFPUIFS JTUIFMJTUPGDPOOFDUJOHTPDLFUT 3FTPVSDFT

Slide 96

Slide 96 text

)&WTTUBUFUSBOTJUJPOTUBSU *UTUBSUTPVUJOUIFTUBUFDBMMFETUBSU TUBSU 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ &NQUZ

Slide 97

Slide 97 text

)&WTTUBUFUSBOTJUJPOTUBSU TUBSUJTUIFTUBUFGPSTUBSUJOHIPTUOBNFSFTPMVUJPO )FSF TUBSUOBNFSFTPMVUJPOGPSCPUI*1WBOE*1WJO QBSBMMFMBOEXBJUVOUJMPOFPGUIFN fi OJTIFT %/44FSWFS TUBSU 2VFSJFT*1WBEESFTTFT 8BJUGPSBOZBOTXFS 2VFSJFT*1WBEESFTTFT

Slide 98

Slide 98 text

)&WTTUBUFUSBOTJUJPOTUBSU 0ODFFJUIFSOBNFSFTPMVUJPOJT fi OJTIFE BEEUIFSFTPMWFEBEESFTTFTUPUIFMJTUPGSFTPMWFE*1 BEESFTTFT TUBSU 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT "OTXFSBOZBEESFTTFT %/44FSWFS "EE ➡︎

Slide 99

Slide 99 text

)&WTTUBUFUSBOTJUJPOTUBSU ➡︎ WD TUBSU *G*1WBEESFTTFTIBWFCFFOSFTPMWFE USBOTJUJPOUPBTUBUFDBMMFEWD WD "OTXFS*1WBEESFTTFT %/44FSWFS

Slide 100

Slide 100 text

)&WTTUBUFUSBOTJUJPOWD WDJTUIFTUBUFGPSTUBSUJOHBDPOOFDUJPOBUUFNQUUP BO*1WBEESFTT*XJMMJOUSPEVDFJUJONPSFEFUBJMMBUFS 4UBSUUPDPOOFDU 4FSWFS WD

Slide 101

Slide 101 text

TUBSU WX 3FUVSOJOHUPTUBSU JGUIFBEESFTTFTPCUBJOFEBGUFS TUBSUJOHOBNFSFTPMVUJPOJT*1WBEESFTTFT JUUSBOTJUJPOTUPBTUBUFDBMMFEWX )&WTTUBUFUSBOTJUJPOTUBSU ➡︎ WX %/44FSWFS "OTXFS*1WBEESFTTFT

Slide 102

Slide 102 text

)&WTTUBUFUSBOTJUJPOWX WX 8BJUGPS*1WBOTXFSGPSNT WXJTUIFTUBUFGPSXBJUJOHVQUPNTGPSUIF OBNFSFTPMVUJPOPG*1WBEESFTTFT %/44FSWFS

Slide 103

Slide 103 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WD "OTXFS*1WBEESFTTFT WX 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT WD *G*1WBEESFTTFTBSFSFTPMWFEXJUIJONT BEEUIFTF*1WBEESFTTFTUPUIFMJTUPGSFTPMWFE*1 BEESFTTFT5IFOUSBOTJUJPOUPBTUBUFDBMMFEWD %/44FSWFS "EE ➡︎

Slide 104

Slide 104 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WD WX 0S *GUIFOBNFSFTPMVUJPOPG*1WBEESFTTFTEPFTOPU fi OJTIXJUIJONT FOEUIFXBJUBOEUSBOTJUJPO UPBTUBUFDBMMFEWD WD 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT %/44FSWFS /PUIJOHXBTBOTXFSFE

Slide 105

Slide 105 text

4PGBS UIFTUBUFTWD WD BOEWDBSFBMMGPS TUBSUJOHBDPOOFDUJPOBUUFNQU 5IFEFTUJOBUJPOGPSFBDITUBUFJTBTGPMMPXT WDUBSHFUT*1WBEESFTTFT WDUBSHFUT*1WBEESFTTFT BOEWDUBSHFUTFJUIFS*1WPS*1WBEESFTTFT WD WD WD )&WTTUBUFUSBOTJUJPOWDWDWD

Slide 106

Slide 106 text

3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT )FSF PCUBJOBOBEESFTTGSPNUIFMJTUPGSFTPMWFE*1 BEESFTTFTBOETUBSUDPOOFDUJOHUPUIBUBEESFTT WD WD WD 4UBSUUPDPOOFDU 4FSWFS )&WTTUBUFUSBOTJUJPOWDWDWD 0CUBJO ⬅︎

Slide 107

Slide 107 text

*GUIFDPOOFDUJPOJTJNNFEJBUFMZFTUBCMJTIFEBGUFS TUBSUJOHUIFBUUFNQU USBOTJUJPOUPBTUBUFDBMMFETVDDFTT SFUVSOUIFDPOOFDUFETPDLFU BOEDPODMVEFUIFNFUIPE WD WD WD TVDDFTT 4FSWFS 4UBSUUPDPOOFDU $POOFDUJPO0, 3FUVSOUIFDPOOFDUFETPDLFU )&WTTUBUFUSBOTJUJPOWDWDWD

Slide 108

Slide 108 text

3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT 0GUFO UIJTEPFTOPUIBQQFO MFBWJOHUIFDPOOFDUJPO JOQSPHSFTT*OUIJTDBTF UIFVTFETPDLFUJTUIFOBEEFE UPUIFMJTUPGDPOOFDUJOHTPDLFUT 4UBSUUPDPOOFDU WD WD WD 4FSWFS )&WTTUBUFUSBOTJUJPOWDWDWD 4UJMMDPOOFDUJOH "EE ➡︎

Slide 109

Slide 109 text

WD WD WD 8BJUGPSDPOOFDUJOHTPDLFUT /PX BGUFSTUBSUJOHBDPOOFDUJPOBUUFNQU JUJTOFDFTTBSZUPXBJUNTGPSBOZPGUIFDPOOFDUJPOT UPCFFTUBCMJTIFE 4FSWFS )&WTTUBUFUSBOTJUJPOWDWDWD 4UBSUUPDPOOFDU 4UJMMDPOOFDUJOH

Slide 110

Slide 110 text

)&WTTUBUFUSBOTJUJPOWDWDWD 8BJUGPS*1W*1WBOTXFS "EEJUJPOBMMZ JGUIFDVSSFOUTUBUFJTFJUIFSWDPSWD JUNFBOTUIFOBNFSFTPMVUJPOGPSBOBEESFTTGBNJMZ IBTOPUZFU fi OJTIFE *OUIJTTJUVBUJPO OFFEUPXBJUGPSCPUIUIFDPOOFDUJPOT BOEUIFOBNFSFTPMVUJPOTJNVMUBOFPVTMZ WD WD ➡︎ *1WOBNFSFTPMVUJPOJOQSPHSFTT ➡︎ *1WOBNFSFTPMVUJPOJOQSPHSFTT %/44FSWFS 4UJMMSFTPMWJOHOBNF

Slide 111

Slide 111 text

)&WTTUBUFUSBOTJUJPOWDWDWD ➡︎ WX WX 5PXBJUGPSUIFN BGUFSTUBSUJOHBDPOOFDUJPOBUUFNQU JUUSBOTJUJPOTUPBTUBUFDBMMFEWX WD WD WD %/44FSWFS 4FSWFS

Slide 112

Slide 112 text

)&WTTUBUFUSBOTJUJPOWX WX WXJTUIFTUBUFGPSXBJUJOH )FSF XBJUGPSFJUIFSBDPOOFDUJPOFTUBCMJTINFOUPSB OBNFSFTPMVUJPOUP fi OJTIXJUIJONTCZEFGBVMU 8BJUGPSNT %/44FSWFS 4FSWFS

Slide 113

Slide 113 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ TVDDFTT *GBOZPGUIFDPOOFDUJPOTJTFTUBCMJTIFEXIJMFXBJUJOH USBOTJUJPOUPTVDDFTT SFUVSOUIFDPOOFDUFETPDLFU BOEDPODMVEFUIFNFUIPE WX TVDDFTT %/44FSWFS "DPOOFDUJPOJTFTUBCMJTIFE 4FSWFS

Slide 114

Slide 114 text

)&WTTUBUFUSBOTJUJPOWX 0S JGOBNFSFTPMVUJPO fi OJTIFTXIJMFXBJUJOH BEEUIF OFXBEESFTTFTUPUIFMJTUPGSFTPMWFE*1BEESFTTFT "UUIJTQPJOU UIFUJNFMJNJUIBTOPUZFUFMBQTFE WX "SFTPMVUJPOJT fi OJTIFE 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT /PUZFUNTPME %/44FSWFS "EE ➡︎ 4FSWFS

Slide 115

Slide 115 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WX 5IFSFGPSF USBOTJUJPOUPWXBHBJOBOE XBJUTGPSUIFSFNBJOEFSPGUIFUJNFMJNJU WX 8BJUGPSSFNBJOEFSPGUIFNT WX 4FSWFS

Slide 116

Slide 116 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ TVDDFTT *GBOZPGUIFDPOOFDUJPOTJTFTUBCMJTIFEEVSJOH UIJTUJNF USBOTJUJPOUPTVDDFTT WX "DPOOFDUJPOJTFTUBCMJTIFE TVDDFTT 8BJUJOHGPSSFNBJOEFSPGUIFNT 4FSWFS

Slide 117

Slide 117 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WD JGOPU USBOTJUJPOUPWDBOETUBSUTBOFXDPOOFDUJPO BUUFNQU WX WD 4UJMMDPOOFDUJOH 4FSWFS

Slide 118

Slide 118 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ *GOPUIJOHXBTIBQQFOFEXJUIJOUIFUJNFMJNJUJOWX BOEBUJNFPVUPDDVST UIFOFYUTUBUFJTEFUFSNJOFE CZUIFTUBUVTPGUIFSFTPVSDF WX 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT %/44FSWFS /PUIJOHXBTIBQQFOFEXJUIJONT 4FSWFS

Slide 119

Slide 119 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WD *GUIFSFBSFTUJMM*1BEESFTTFTUIBUIBWFOPUCFFO BUUFNQUFEGPSDPOOFDUJPO USBOTJUJPOUPWD WX 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT "OZ WD %/44FSWFS 4FSWFS

Slide 120

Slide 120 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ WX PUIFSXJTF NPWFCBDLUPWXUPDPOUJOVFXBJUJOH GPSDPOOFDUJPOT WX 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ WD %/44FSWFS 4FSWFS

Slide 121

Slide 121 text

)&WTTUBUFUSBOTJUJPOWX ➡︎ GBJMVSF 6QUPUIJTQPJOU JGBMMOBNFSFTPMVUJPOTPSDPOOFDUJPO BUUFNQUTGBJMBOEUIFSFTPVSDFTCFDPNFFNQUZ USBOTJUJPOUPBTUBUFDBMMFEGBJMVSF 5IFOSBJTFBOFYDFQUJPOBOEFYJUUIFQSPDFTT WX 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ GBJMVSF &NQUZ TUBSU WD

Slide 122

Slide 122 text

)FSFJTUIFDPNQMFUFPWFSWJFXJODMVEJOHUIFTUBUFTJOUSPEVDFE TPGBSBMPOHXJUIBTUBUFSFQSFTFOUJOHVTFSTQFDJ fi FEUJNFPVUT WD GBJMVSF WX WD WD TUBSU WX )&WTTUBUFUSBOTJUJPO0WFWJFX TVDDFTT UJNFPVU

Slide 123

Slide 123 text

8JUIVOEFSTUBOEJOHUIJT XFDBOJNQMFNFOUUIFTUBUFUSBOTJUJPOTJODPEF )&WTTUBUFUSBOTJUJPO0WFWJFX WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU

Slide 124

Slide 124 text

def self.tcp(host, port, ...) # Do something ensure # ... end /PX MFUNFCSJF fl ZJOUSPEVDF UIFBDUVBMDPEFGPS4PDLFUUDQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W

Slide 125

Slide 125 text

def self.tcp(host, port, ...) # ... loop do case state when :start # ... end end ensure # ... end *OUIJTJNQMFNFOUBUJPO VTF,FSOFMMPPQBOEDBTFTUBUFNFOUTUPQFSGPSN BQQSPQSJBUFBDUJPOTGPSFBDITUBUF *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W ,FSOFMMPPQ DBTFTUBUFNFOUT

Slide 126

Slide 126 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start # ... end end ensure # ... end 'JSTU TFUDVSSFOUTUBUFUPTUBSUBTBOJOJUJBMTUBUF CFGPSFTUBSUJOHUIFMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&W *OJUJBMJ[FTUBUF

Slide 127

Slide 127 text

case state when :start # ... h 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 } ) # ... 5IJTJTTUBSU $SFBUFUISFBETGPSFBDIBEESFTTGBNJMZBOE TUBSUOBNFSFTPMVUJPOXJUIJOFBDIUISFBE *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTUBSU hostname_resolution_args = [host, port, hostname_resolution_queue] $SFBUFUISFBETGPSFBDIBEESFTTGBNJMZ &YFDVUFOBNFSFTPMVUJPONFUIPE

Slide 128

Slide 128 text

case state when :start # ... hostname_resolution_queue = HostnameResolutionQueue.new(...) hostname_resolution_waiting = h # ... remaining = resolv_timeout ? second_to_timeout(...) : nil hostname_resolved, _, = IO.select( # ... 5IFO XBJUGPSFJUIFS*1WPS*1WOBNFSFTPMVUJPO UP fi OJTI)FSF VTF*0TFMFDUUPXBJUGPSOBNF SFTPMVUJPO5IFSFBTPOGPSUIJTXJMMCFFYQMBJOFEMBUFS *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTUBSU (hostname_resolution_waiting, nil, nil, remaining) hostname_resolution_queue.waiting_pipe 8BJUGPSOBNFSFTPMVUJPOUP fi OJTI

Slide 129

Slide 129 text

case state when :start # ... family_name, res = hostname_resolution_queue.get if res.is_a? Exception # ... else state = case family_name when :ipv6 then :v6c when :ipv4 then ? :v4c : :v4w end selectable_addrinfos.add(family_name, res) # ... end # ... next # ... 0ODFOBNFSFTPMVUJPOJT fi OJTIFE BEEUIFPCUBJOFE BEESFTTFTUPUIFMJTUPGSFTPMWFE*1BEESFTTFT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTUBSU "EEUIFPCUBJOFEBEESFTTFT 5IFMJTUPGSFTPMWFE*1BEESFTTFT

Slide 130

Slide 130 text

case state when :start # ... family_name, res = hostname_resolution_queue.get if res.is_a? Exception # ... else state = case family_name when :ipv6 then :v6c when :ipv4 then < end selectable_addrinfos.add(family_name, res) # ... end # ... next # ... %FUFSNJOFUIFOFYUTUBUFCBTFEPOUIFPCUBJOFE BEESFTT BOEUIFOFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTUBSU %FUFSNJOFUIFOFYUTUBUF ⬅︎ All name resolutions are finished?> ? :v4c : :v4w

Slide 131

Slide 131 text

case state when :v4w ipv6_resolved, _, = IO.select( # ... 5IJTJTWX *0TFMFDUJTVTFEBHBJOUP XBJUGPS*1WOBNFSFTPMVUJPOGPSNT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) 8BJUGPSOBNFSFTPMVUJPOUP fi OJTI 3&40-65*0/@%&-":NT

Slide 132

Slide 132 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 # ... else # ... end # ... *GUIFOBNFSFTPMVUJPOJT fi OJTIFEXJUIJONT BEEUIFOFXMZPCUBJOFEBEESFTTFTUPUIFMJTUPG SFTPMWFE*1BEESFTTFT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX Exception (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) "EEUIFPCUBJOFEBEESFTTFT 5IFMJTUPGSFTPMWFE*1BEESFTTFT

Slide 133

Slide 133 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 # ... %FUFSNJOFUIFOFYUCBTFEPOXIFUIFSUIFOBNF SFTPMVUJPOXBT fi OJTIFEXJUIJOUIFBMMPUUFEUJNF BOEUIFOFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX Exception (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) %FUFSNJOFUIFOFYUTUBUF ⬅︎

Slide 134

Slide 134 text

case state when :v6c, :v4c, v46c # ... WD WD BOEWDBSFEJ ff FSFOUTUBUFT CVUTJODF UIFDPEFTGPSFBDIJTFYBDUMZUIFTBNF UIFZBSFHSPVQFEUPHFUIFSBTBTJOHMFDBTF *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWDWDWD

Slide 135

Slide 135 text

case state when :v6c, :v4c, v46c # ... addrinfo = selectable_addrinfos.get # ... connection_attempt_delay_expires_at = current_clocktime + CONNECTION_ATTEMPT_DELAY # ... socket = Socket.new( socket.bind(local_addrinfo) if local_addrinfo result = socket.connect_nonblock(addrinfo, exception: false) # ... )FSF fi STUPCUBJOBOBEESFTTGSPNUIFMJTUPGSFTPMWFE *1BEESFTTFTBOEUIFOTUBSUBDPOOFDUJPOBUUFNQU *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWDWDWD (addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) 0CUBJOBOBEESFTT 4UBSUBDPOOFDUJPOBUUFNQU 5IFMJTUPGSFTPMWFE*1BEESFTTFT 0CUBJOUJNFPVUQFSJPE

Slide 136

Slide 136 text

case state when :v6c, :v4c, v46c # ... addrinfo = selectable_addrinfos.get # ... 1FSUIF3'$ BEESFTTFTTIPVMECFTPSUFECFGPSF DPOOFDUJOH5IJTJNQMFNFOUBUJPOTJNQMJ fi FTUIFQSPDFTT CZBMUFSOBUJOHCFUXFFO*1WBOE*1WBEESFTTFT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWDWDWD precedences = case @last_family when :ipv4, nil then [:ipv6, :ipv4] when :ipv6 then [:ipv4, :ipv6] end precedences.each do |family_name| addrinfo = @addrinfo_dict[family_name]&.shift next unless addrinfo @last_family = family_name return addrinfo end 0CUBJOBOBEESFTT GSPNBEJ ff FSFOUBEESFTTGBNJMZ UIBOQSFWJPVTMZTFMFDUFE QSJPSJUJ[JOH*1WJOJUJBMMZ

Slide 137

Slide 137 text

case state when :v6c, :v4c, v46c # ... case result when 0 connected_socket = socket state = :success when Socket connected_socket = result state = :success when :wait_writable connecting_sockets.add(socket, addrinfo) state = :v46w end # ... next "GUFSTUBSUJOHUIFDPOOFDUJPOBUUFNQU EFUFSNJOFUIF OFYUTUBUFCBTFEPOXIFUIFSUIFDPOOFDUJPOXBTNBEF JNNFEJBUFMZ BOEUIFOFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWDWDWD %FUFSNJOFUIFOFYUTUBUF ⬅︎

Slide 138

Slide 138 text

case state when :v6c, :v4c, v46c # ... case result when 0 connected_socket = socket state = :success when Socket connected_socket = result state = :success when :wait_writable connecting_sockets.add(socket, addrinfo) state = :v46w end # ... next *GUIFDPOOFDUJPODBOUCFFTUBCMJTIFEJNNFEJBUFMZ BEEUIFTPDLFUVTFEGPSUIFBUUFNQUUPUIFMJTUPG DPOOFDUJOHTPDLFUTCFGPSFEFUFSNJOJOHUIFOFYUTUBUF *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWDWDWD "EEUIFTPDLFUVTFE 5IFMJTUPGDPOOFDUJOHTPDLFUT

Slide 139

Slide 139 text

case state when :v46w # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 5IJTJTWX )FSF JUOFFETUPTJNVMUBOFPVTMZXBJUGPSFJUIFS FTUBCMJTINFOUTPGDPOOFDUJPOTPS fi OJTIPGUIF OBNFSFTPMVUJPO

Slide 140

Slide 140 text

case state when :v46w # ... ...tname_resolved, ...nectable_sockets, = IO.select( # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX *0TFMFDUJTVTFEIFSFBHBJOGPSUIJTQVSQPTF (...tname_resolution_waiting, ...necting_sockets.all, ..., ...aining) *0TFMFDUJTDBMMFE

Slide 141

Slide 141 text

*0TFMFDUJTBNFUIPEUIBUXBJUTGPSSFBEJOFTTPG*0 PCKFDUT *UUBLFT*0PCKFDUTXBJUJOHGPSSFBEJOHBOE *0PCKFDUTXBJUJOHGPSXSJUJOHBTBSHVNFOUT 5IFNFUIPEXBJUTVOUJMBUMFBTUPOFPGUIFTFPCKFDUT CFDPNFTSFBEZGPSSFBEJOHPSXSJUJOH *0TFMFDU "OBSSBZPG*0PCKFDUTXBJUJOHGPSSFBEJOH "OBSSBZPG*0PCKFDUTXBJUJOHGPSXSJUJOH IO.select(readfds, writefds, nil, timeout)

Slide 142

Slide 142 text

5IJTNFUIPEBMTPBMMPXTTQFDJGZJOHBUJNFPVUQFSJPEBT BOBSHVNFOU *USFMFBTFTUIFXBJUFWFOJGUIFSFBSFOPPCKFDUTSFBEZGPS SFBEJOHPSXSJUJOHJGJUUJNFTPVU *0TFMFDU IO.select(readfds, writefds, nil, timeout) "UJNFPVUQFSJPE

Slide 143

Slide 143 text

5IFSFUVSOWBMVFJTTPNFBSSBZTPG*0PCKFDUTUIBUIBWF CFDPNFSFBEZGPSSFBEJOHPSXSJUJOH *GJUUJNFTPVU JUSFUVSOTOJM *0TFMFDU rs, ws, _ = IO.select(readfds, writefds, nil, timeout) [[, ...], [, ...], ...]

Slide 144

Slide 144 text

case state when :v46w # ... ...tname_resolved, ...nectable_sockets, = IO.select( # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 4JODFUIF4PDLFUGBNJMZPGDMBTTFTJOIFSJUTGSPN*0 DMBTT *0TFMFDUDBOBMTPXBJUGPS4PDLFUPCKFDUT 6UJMJ[JOHUIJT JOWX UIFDPOOFDUJOHTPDLFUTBSF QBTTFEUPUIJTNFUIPEBT*0PCKFDUTXBJUJOHGPSXSJUJOH (...tname_resolution_waiting, connecting_sockets.all, nil, ...aining) $POOFDUJOHTPDLFUTBTXSJUJOH*0PCKFDUT Socket.ancestors => [Socket, BasicSocket, IO, # ... BasicObject]

Slide 145

Slide 145 text

case state when :v46w # ... ...tname_resolved, connectable_sockets, = IO.select( # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 8IFOBDPOOFDUJPOJTFTUBCMJTIFEPSGBJMTPOBOZPG UIFTPDLFUTQBTTFEBTBSHVNFOUT *0TFMFDUDPOTJEFST UIFTFUPCFXSJUBCMF*0PCKFDUT 5IFO*0TFMFDUSFMFBTFTUIFXBJU BOESFUVSOTBOBSSBZ PGUIFSFMFWBOUTPDLFUTBTXSJUBCMF*0PCKFDUT (...tname_resolution_waiting, connecting_sockets.all, nil, ...aining) 4PDLFUTBTXSJUBCMF*0PCKFDUT

Slide 146

Slide 146 text

case state when :v46w # ... ...tname_resolved, connectable_sockets, = IO.select( # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 5IJTBMMPXTVTUPXBJUGPSUIFFTUBCMJTINFOUPG DPOOFDUJPOT4P IPXTIPVMEXFXBJUGPSUIF fi OJTIPGUIFOBNFSFTPMVUJPO (...tname_resolution_waiting, connecting_sockets.all, nil, ...aining)

Slide 147

Slide 147 text

case state when :v46w # ... ...tname_resolved, connectable_sockets, = IO.select( # ... (, connecting_sockets.all, nil, ...aining) *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 5IFEJ ff i DVMUZJTUIBU UIFOBNFSFTPMVUJPOUISFBETBSFOPU*0PCKFDUTBOE DBOOPUCFXBJUFEGPSJO*0TFMFDU $BOUQBTTOBNFSFTPMVUJPOUISFBET

Slide 148

Slide 148 text

case state when :v46w # ... ...tname_resolved, connectable_sockets, = IO.select( # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 5PSFTPMWFUIJT VTF*0QJQF (...tname_resolution_waiting, connecting_sockets.all, nil, ...aining)

Slide 149

Slide 149 text

*0QJQFSFUVSOTUXPJOUFSDPOOFDUFE*0PCKFDUT 0OFPGUIFTFJTGPSSFBEJOHBOEUIFPUIFSJTGPSXSJUJOH *0QJQF rpipe, wpipe = IO.pipe "O*0PCKFDUGPSSFBEJOH "O*0PCKFDUGPSXSJUJOH

Slide 150

Slide 150 text

*0QJQF 8IFOZPVXSJUFUPUIFXSJUJOH*0PCKFDU ZPVDBOSFBEUIBUGSPNUIFSFBEJOH*0PCKFDU rpipe, wpipe = IO.pipe Thread.new(wpipe) do |w| w.puts "foo" w.close end p rpipe.gets # => "foo" 8SJUFUIFXSJUJOH*0PCKFDU 5IFOUIFSFBEJOH*0PCKFDUDBOCFSFBE

Slide 151

Slide 151 text

case state when :start # ... hostname_resolution_queue = HostnameResolutionQueue.new(...) # ... *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX *OUIJTJNQMFNFOUBUJPO *0QJQFXBTDBMMFEBUTUBSUUP DSFBUFBQBJSPG*0PCKFDUT class HostnameResolutionQueue def initialize(size) # ... @rpipe, @wpipe = IO.pipe end # ... $SFBUFBQBJSPG*0PCKFDUT

Slide 152

Slide 152 text

case state when :start # ... hostname_resolution_queue = HostnameResolutionQueue.new(...) # ... *0QJQF 0GUIFTFUXP*0PCKFDUT UIFPOFGPSXSJUJOHJT class HostnameResolutionQueue # ... def waiting_pipe [@wpipe] end # ... hostname_resolution_waiting = hostname_resolution_queue.waiting_pipe hostname_resolution_args = [host, port, hostname_resolution_queue] 5IFXSJUJOH*0PCKFDU 5IFXSJUJOH*0PCKFDU BOEPUIFSBSHVNFOUT

Slide 153

Slide 153 text

case state when :start # ... hostname_resolution_queue = HostnameResolutionQueue.new(...) 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 } ) # ... *0QJQF QBTTFEBTBOBSHVNFOUUPUIFOBNFSFTPMVUJPO UISFBET hostname_resolution_waiting = hostname_resolution_queue.waiting_pipe hostname_resolution_args = [host, port, hostname_resolution_queue] 1BTTUIFBSHTJODMVEJOHUIFXSJUJOH*0PCKFDU

Slide 154

Slide 154 text

case state when :start # ... thread = Thread.new(*thread_args) { |*thread_args| hostname_resolution(*thread_args) } *0QJQF 0ODFOBNFSFTPMVUJPOJT fi OJTIFEJOUIFUISFBE JUXSJUFTUPUIFXSJUJOH*0PCKFDUUPOPUJGZDPNQMFUJPO def self.hostname_resolution(family, ..., hostname_resolution_queue) resolved_addrinfos = Addrinfo.getaddrinfo(...) hostname_resolution_queue.add_resolved(family, resolved_addrinfos) # ... def add_resolved(family, resolved_addrinfos) @mutex.synchronize do @queue.push [family, resolved_addrinfos] @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED # ... 8SJUFUPUIFXSJUJOH*0PCKFDU

Slide 155

Slide 155 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX case state when :v46w # ... ...tname_resolved, connectable_sockets, = IO.select( # ... .FBOXIJMF UIFSFBEJOH*0PCKFDUDSFBUFEXJUI*0QJQF JTQBTTFEUP*0TFMFDUJONBJOUISFBE (hostname_resolution_waiting, connecting_sockets.all, nil, ...aining) 5IFSFBEJOH*0PCKFDU

Slide 156

Slide 156 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... 5IJT*0PCKFDUXJMMCFSFBEBCMFPODFOBNFSFTPMVUJPO JT fi OJTIFEJOUIFDIJMEUISFBET 5IFO*0TFMFDUXJMMSFMFBTFUIFXBJUBOESFUVSOUIJT SFBEJOH*0PCKFDU (hostname_resolution_waiting, connecting_sockets.all, nil, ...aining) 5IFSFBEJOH*0PCKFDU 3FBEBCMF*0PCKFDUT

Slide 157

Slide 157 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... 5IJTJTUIFUSJDLUPBMMPXGPSXBJUJOHGPSCPUI UIFDPNQMFUJPOPGDPOOFDUJPOTBOEOBNFSFTPMVUJPO (hostname_resolution_waiting, connecting_sockets.all, nil, ...aining) #PUIDPOOFDUJPOTBOEOBNFSFTPMVUJPODBOCFXBJU

Slide 158

Slide 158 text

case state when :start # ... hostname_resolution_queue = HostnameResolutionQueue.new(...) hostname_resolution_waiting = h # ... hostname_resolved, _, = IO.select( # ... when :v4w ipv6_resolved, _, = IO.select( # ... (hostname_resolution_waiting, nil, nil, remaining) hostname_resolution_queue.waiting_pipe *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTUBSUWX "OEJUJTUIFSFBTPOXIZTUBSUBOEWXVTFE*0TFMFDU UPXBJUGPSOBNFSFTPMVUJPO (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) 8BJUXJUIUIFSFBEJOH*0PCKFDU 8BJUXJUIUIFSFBEJOH*0PCKFDU

Slide 159

Slide 159 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX case state when :v46w # ... remaining = s hostname_resolved, connectable_sockets, = IO.select( # ... -FUTSFUVSOUPWX 4FUUIFUJNFPVUCZQBTTJOH*0TFMFDUUIFUJNFUPXBJU GPSDPOOFDUJPOT (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) second_to_timeout(connection_attempt_delay_expires_at) 4FUUJNFPVU $BMDVMBUFSFNBJOJOHUJNFGSPNUIFUJNFPVUQFSJPE

Slide 160

Slide 160 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) *G*0TFMFDUSFUVSOTBXSJUBCMF*0PCKFDUXJUIJOUIF XBJUJOHQFSJPE JUNFBOTUIBUBTJUVBUJPOIBTBSJTFO XIFSFTPDLFUTIBWFFJUIFSTVDDFTTGVMMZDPOOFDUFEPS GBJMFEUPDPOOFDU *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX 8IFO*0TFMFDUSFUVSOTXSJUBCMF*0PCKFDUT 3FBDIUIJTCMPDL

Slide 161

Slide 161 text

case state when :v46w # ... if connectable_sockets&.any? while (connectable_socket = connectable_sockets.pop) # ... sockopt = c is_connected = sockopt.int.zero? # ... if is_connected # ... else # ... end # ... next *OUIJTDBTF EFUFSNJOFUIFOFYUTUBUFCBTFEPO XIFUIFSUIFTPDLFUTXFSFDPOOFDUFEPSOPU BOEUIFOFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX connectable_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) %FUFSNJOFUIFOFYUTUBUF $IFDLUIFDPOOFDUJPOTUBUVT ⬅︎

Slide 162

Slide 162 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? # ... else # ... end # ... next 0SJG*0TFMFDUSFUVSOTSFBEBCMF*0PCKFDUTXJUIJOUIF XBJUJOHQFSJPE JUNFBOTUIBUOBNFSFTPMVUJPOJT fi OJTIFE *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) 8IFO*0TFMFDUSFUVSOTSFBEBCMF*0PCKFDUT 3FBDIUIJTCMPDL

Slide 163

Slide 163 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? family_name, res = hostname_resolution_queue.get selectable_addrinfos.add(family_name, res) unless res.is_a? E else # ... end # ... next *OUIJTDBTF BEEUIFPCUBJOFEBEESFTTFTUPUIFMJTUPG SFTPMWFE*1BEESFTTFT *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX Exception (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) "EEUIFPCUBJOFEBEESFTTFT 5IFMJTUPGSFTPMWFE*1BEESFTTFT

Slide 164

Slide 164 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? family_name, res = hostname_resolution_queue.get selectable_addrinfos.add(family_name, res) unless res.is_a? E else # ... end # ... next 5PXBJUGPSUIFSFNBJOJOHUJNF LFFQUIFDVSSFOUTUBUF BUWX BOEFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) &OUFSUIFOFYUMPPQXJUIWXTUBUF Exception

Slide 165

Slide 165 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? family_name, res = hostname_resolution_queue.get selectable_addrinfos.add(family_name, res) unless res.is_a? E else # ... end # ... next 0SJG*0TFMFDUUJNFTPVUBOESFUVSOTOJM JUNFBOTUIBU OFJUIFSBDPOOFDUJPOOPSUIFOBNFSFTPMVUJPOXFSF fi OJTIFEXJUIJOUIFBMMPUUFEUJNF *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) 8IFO*0TFMFDUSFUVSOTOJM 3FBDIUIJTCMPDL Exception

Slide 166

Slide 166 text

case state when :v46w # ... hostname_resolved, connectable_sockets, = IO.select( # ... if connectable_sockets&.any? # ... elsif hostname_resolved&.any? family_name, res = hostname_resolution_queue.get selectable_addrinfos.add(family_name, res) unless res.is_a? E else # ... end # ... next *OUIJTDBTF EFUFSNJOFUIFOFYUTUBUFCBTFEPOUIF DVSSFOUSFTPVSDFTTUBUVT BOEUIFOFOUFSUIFOFYUMPPQ *NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WWX (hostname_resolution_waiting, connecting_sockets.all, nil, remaining) %FUFSNJOFUIFOFYUTUBUF ⬅︎ Exception

Slide 167

Slide 167 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WGBJMVSF ret = loop do case state # ... when :success # ... when :failure raise last_error when :timeout # ... end end 5IFTUBUFTJOUSPEVDFEIFSFBGUFSBMMSFQSFTFOUUIF DPNQMFUJPOPGTUBUFUSBOTJUJPOT GBJMVSFXIJDIJTSFBDIFEJGBMMOBNFSFTPMVUJPOTPS BMMDPOOFDUJPOBUUFNQUTGBJM SBJTFBOFYDFQUJPO XJUIUIFMBTUDBQUVSFEFSSPS 3BJTFBOFYDFQUJPO

Slide 168

Slide 168 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WUJNFPVU ret = loop do case state # ... when :success # ... when :failure raise last_error when :timeout raise Errno::ETIMEDOUT, "user specified timeout" end end *GBVTFSTQFDJ fi FEUJNFPVUPDDVST SFBDIUJNFPVU BOESBJTFBOFYDFQUJPOJOEJDBUJOHJU 3BJTFBOFYDFQUJPO

Slide 169

Slide 169 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WTVDDFTT ret = loop do case state # ... when :success break connected_socket when :failure raise last_error when :timeout raise Errno::ETIMEDOUT, "user specified timeout" end end TVDDFTTXIJDIJTSFBDIFEXIFOPOFPGUIFDPOOFDUJPOT JTFTUBCMJTIFE JTIFSF #SFBLUIFMPPQXJUIUIFDPOOFDUFETPDLFU #SFBLUIFMPPQ

Slide 170

Slide 170 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WDMFBOVQ def self.tcp(host, port, ...) # ... ret = loop do # ... end # ... ensure # ... hostname_resolution_threads.each do |thread| thread&.exit end hostname_resolution_queue&.close_all connecting_sockets.each do |connecting_socket| connecting_socket.close unless connecting_socket.closed? end end "GUFSCSFBLJOHPVUPGUIFMPPQ DMFBOVQUISFBET QJQFT BOEPUIFSTPDLFUTJOFBDIDPOOFDUJPOBUUFNQUT $MFBOVQ

Slide 171

Slide 171 text

*NQMFNFOUBUJPOPG4PDLFUUDQXJUI)&WFYJU def self.tcp(host, port, ...) # ... ret = loop do # ... end if block_given? begin yield ret ensure ret.close end else ret end ensure # ... end SFUVSOUIFDPOOFDUFETPDLFUBOEUIFNFUIPEFYJUT &YFDVUFCMPDLXJUIUIFDPOOFDUFETPDLFU 3FUVSOUIFDPOOFDUFETPDLFU

Slide 172

Slide 172 text

4PGBS UIFLFZBTQFDUTPGUIF)&WJNQMFNFOUBUJPO PG4PDLFUUDQIBWFCFFOJOUSPEVDFE )PXFWFS GSPNBQSBDUJDBMTUBOEQPJOU UIFSFBSFTPNFBEEJUJPOBMDPOTJEFSBUJPOT UIBUOFFEUPCFBEESFTTFE

Slide 173

Slide 173 text

"EEJUJPOBMDPOTJEFSBUJPOT 'JSTUPGBMM EVSJOHUIFJNQMFNFOUBUJPO *EJTDPWFSFEBDBTFUIBU XBTOPUDPWFSFECZUIFFBSMJFSTUBUFUSBOTJUJPOEJBHSBN WD GBJMVSF WX WD WD TUBSU WX TVDDFTT UJNFPVU

Slide 174

Slide 174 text

"EEJUJPOBMDPOTJEFSBUJPOT WX "O*1WBEESFTTSFTPMWFE 4FSWFS %/44FSWFS -FUTDPOTJEFSUIFTJUVBUJPOMJLFUIJT &JUIFS*1WPS*1WOBNFSFTPMVUJPOIBTCFFO fi OJTIFE POFPSUIFPUIFS 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT *1WJTTUJMMSFTPMWJOH &NQUZ "EE ➡︎

Slide 175

Slide 175 text

"EEJUJPOBMDPOTJEFSBUJPOT WX %/44FSWFS $POOFDUJPOBUUFNQUTIBWFCFFOTUBSUFEUP BMMSFTPMWFE*1BEESFTTFTTPGBS 4UBSUBDPOOFDUJPOUPUIF*1WBEESFTT 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT *1WJTTUJMMSFTPMWJOH &NQUZ 4FSWFS 0CUBJO ⬅︎

Slide 176

Slide 176 text

"EEJUJPOBMDPOTJEFSBUJPOT WX %/44FSWFS 4VCTFRVFOUMZ BMMPGUIPTFBUUFNQUTIBWFGBJMFE $POOFDUJPOTGBJM 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ *1WJTTUJMMSFTPMWJOH &NQUZ 4FSWFS

Slide 177

Slide 177 text

"EEJUJPOBMDPOTJEFSBUJPOT WX %/44FSWFS *OUIJTTDFOBSJP UIFGPMMPXJOHTJUVBUJPOPDDVS ɾ5IFMJTUPGSFTPMWFE*1BEESFTTFTBOE ɾUIFMJTUPGDPOOFDUJOHTPDLFUTBSFFNQUZ ɾ"OBNFSFTPMVUJPOGPSUIFPUIFSBEESFTTGBNJMZJT ɾTUJMMJOQSPHSFTTJOUIFCBDLHSPVOE 3FTPVSDFT $POOFDUJOHTPDLFUT 3FTPMWFE*1BEESFTTFT &NQUZ *1WJTTUJMMSFTPMWJOH &NQUZ 4FSWFS

Slide 178

Slide 178 text

*OUIJTDBTF TIPVMEJUUSBOTJUJPOUPGBJMVSFCFDBVTFUIF SFTPVSDFTBSFOPXFNQUZ 0STIPVMEJUUSBOTJUJPOUPWXUPXBJUGPSUIFSFTPMVUJPOPGUIF PUIFSBEESFTTGBNJMZ "EEJUJPOBMDPOTJEFSBUJPOT WD GBJMVSF WX WD WD TUBSU WX TVDDFTT UJNFPVU

Slide 179

Slide 179 text

"EEJUJPOBMDPOTJEFSBUJPOT 5IFTQFDJ fi DBUJPOT GPSUIJTDBTFBSFOPUEF fi OFEJO3'$ 5IFSFGPSF JUJTOFDFTTBSZUPDPOTJEFS IPX4PDLFUUDQTIPVMEIBOEMFUIJTTJUVBUJPO

Slide 180

Slide 180 text

'PMMPXJOHEJTDVTTJPOTXJUI!OBSVTFBOEPUIFS 3VCZDPNNJUUFST XFEFDJEFEUPBMJHOXJUIUIFTQFDJ fi DBUJPOT PGUIFQSFWJPVTWFSTJPOPG4PDLFUUDQBOEDPOUJOVFUPXBJUGPS OBNFSFTPMVUJPOJOWX "EEJUJPOBMDPOTJEFSBUJPOT WD GBJMVSF WX WD WD TUBSU WX TVDDFTT UJNFPVU

Slide 181

Slide 181 text

"EEJUJPOBMDPOTJEFSBUJPOT "EEJUJPOBMMZ 4PDLFUUDQIBTSFTPMW@UJNFPVULFZXPSE BSHVNFOUUIBUBMMPXTUPTFUBUJNFPVUGPSOBNFSFTPMVUJPO 8IFOUIJTBSHVNFOUJTVTFEBOEBTJUVBUJPOMJLFUIJTBSJTFT USBOTJUJPOUPGBJMVSFBOESBJTFBOFYDFQUJPO WD GBJMVSF WX WD WD TUBSU WX TVDDFTT UJNFPVU

Slide 182

Slide 182 text

4FDPOEMZ UIJTVQEBUFIBTTJHOJ fi DBOUMZDIBOHFEUIF JOUFSOBMJNQMFNFOUBUJPOPG4PDLFUUDQ XJUIUIFDPEF OPXNPSFUIBOUFOUJNFTMPOHFSUIBOCFGPSF "EEJUJPOBMDPOTJEFSBUJPOT #FGPSF MJOFT "GUFS MJOFT

Slide 183

Slide 183 text

5IJTJODMVEFTQSPDFTTFTUIBUBSFSFMBUJWFMZDPTUMZJOUFSNTPG FYFDVUJPO TVDIBTDSFBUJOHUISFBETBOEDBMMJOH*0TFMFDU "EEJUJPOBMDPOTJEFSBUJPOT TUBDLQSPGE fl BNFHSBQIJOMPDBMFOWJSPONFOU "QQMF..BY #FGPSF 3VCZ "GUFS DSFBUJOHBOEIBOEMJOHUISFBET *0TFMFDU

Slide 184

Slide 184 text

"EEJUJPOBMDPOTJEFSBUJPOT 5IFTFFYFDVUJPODPTUTEJSFDUMZJNQBDUSVOUJNF BOEBTBSFTVMU UIFFYFDVUJPOUJNFIBTSPVHIMZEPVCMFE DPNQBSFEUPCFGPSFUIFDIBOHFT Benchmark.bmbm do |x| x.report do 100.times { Socket.tcp("localhost", 9292).close } end end #FGPSF 3VCZ "GUFS *OMPDBMFOWJSPONFOU "QQMF..BY

Slide 185

Slide 185 text

"EEJUJPOBMDPOTJEFSBUJPOT 0OUIFPUIFSIBOE )&WJTEFTJHOFEUPQSFWFOUUIFXPSTUDBTFTDFOBSJP XIFSFOPDPOOFDUJPOTBSFDPNQMFUFEFWFOBGUFSB QSPMPOHFEQFSJPE 8FDBOBENJUUIBUTPNFEFHSFFPGQFSGPSNBODF EFHSBEBUJPOJTVOBWPJEBCMFJOPSEFSUPBEESFTTUIFTF JTTVFT

Slide 186

Slide 186 text

"TBDPNQSPNJTFCFUXFFOUIFTFUXPQFSTQFDUJWFT BOPQUJPO UPFOBCMFPSEJTBCMF)&WXBTJOUSPEVDFEBTBGFBUVSF 5IJTDBOCFDPOUSPMMFECZQBTTJOHUSVFPSGBMTFUPUIF GBTU@GBMMCBDLLFZXPSEBSHVNFOUXIFODBMMJOH4PDLFUUDQ "EEJUJPOBMDPOTJEFSBUJPOT @tcp_fast_fallback = true class << self attr_accessor :tcp_fast_fallback end def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil, fast_fallback: tcp_fast_fallback, &block) &OBCMFPSEJTBCMF)&W

Slide 187

Slide 187 text

"EEJUJPOBMDPOTJEFSBUJPOT #ZEFGBVMU UIFGBTU@GBMMCBDLPQUJPOJTTFUUPUSVF NFBOJOH)&WJTFOBCMFE *GGBMTFJTFYQMJDJUMZQBTTFE JUXJMMJOWPLFUIFDPEFGPS 4PDLFUUDQBTJUXBTCFGPSF)&WXBTJOUSPEVDFE *EFBMMZ UIFQFSGPSNBODFXJMMFWFOUVBMMZJNQSPWFUPUIFQPJOU XIFSFUIJTPQUJPOJTOPMPOHFSOFFEFE CVUGPSOPX JUSFNBJOT BGVUVSFDIBMMFOHF Socket.tcp(HOSTNAME, PORT, fast_fallback: false) do |socket| socket.write "GET / HTTP/1.0\r\n\r\n" print socket.read end

Slide 188

Slide 188 text

8JUIUIFTFBEKVTUNFOUTNBEF 4PDLFUUDQXJUI)&WTVQQPSUFE JTOPXDPNQMFUF

Slide 189

Slide 189 text

%FNP

Slide 190

Slide 190 text

$PEFTGPSEFNP $MJFOU require "socket" HOSTNAME = "localhost" PORT = 4567 Socket.tcp(HOSTNAME, PORT) do |socket| socket.write "Hi\r\n" print socket.read end 5IJTCMPDLXPVMECFFYFDVUFE PODFBDPOOFDUJPOJTFTUBCMJTIFE 4UBOEBSEPVUQVUUIFSFTQPOTFSFUVSOFEGSPNUIFUBSHFUTFSWFS &YFDVUF4PDLFUUDQ

Slide 191

Slide 191 text

$PEFTGPSEFNP 4FSWFS require "socket" require "optparse" class Server ADDRESS_FAMILIES = { IPv6: [Socket::AF_INET6, "::1"], IPv4: [Socket::AF_INET, "127.0.0.1"], } #... def accept_loop # ... end end if child_pid = fork Server.new(:IPv6).accept_loop Process.waitpid(child_pid) else Server.new(:IPv4).accept_loop end 4UBSUUXPQSPDFTTFTUPIBOEMFSFRVFTUT UPCPUI*1WBOE*1WBEESFTTFT )BOEMFSFRVFTUTXJUIUIJTNFUIPE

Slide 192

Slide 192 text

$PEFTGPSEFNP 4FSWFS class Server # ... def accept_loop target_family = ARGV.getopts("", "sleep:")["sleep"]&.to_sym sleep if target_family == @version @socket.listen(5) loop do conn, ai = @socket.accept puts "Received #{@version} request" conn.readpartial(128) conn.write("Connection OK: #{ai.ip_address} (#{@version})\n") conn.close # ... end end end 8BJUGPSSFRVFTUT 3FUVSOBSFTQPOTF "DDFQUBSFRVFTU

Slide 193

Slide 193 text

$PEFTGPSEFNP 4FSWFS class Server # ... def accept_loop target_family = ARGV.getopts("", "sleep:")["sleep"]&.to_sym sleep if target_family == @version @socket.listen(5) loop do conn, ai = @socket.accept puts "Received #{@version} request" conn.readpartial(128) conn.write("Connection OK: #{ai.ip_address} (#{@version})\n") conn.close # ... end end end 8BJUGPSSFRVFTUT 8IFOFYFDVUFEXJUIUIFBEESFTTGBNJMZ *1W*1W BT"3(7 JUPCUBJOTUIFBEESFTTGBNJMZGSPN"3(7 4MFFQUIFTFSWFSQSPDFTTCFGPSF XBJUJOHGPSSFRVFTUT 5IJTTJNVMBUFTBTJUVBUJPOXIFSF BGUFSTUBSUJOHBDPOOFDUJPOBUUFNQUUPBDFSUBJO BEESFTT UIFDPOOFDUJPOJTOPUFTUBCMJTIFETPPO

Slide 194

Slide 194 text

3VOUIFEFNP

Slide 195

Slide 195 text

:PVDBOTFFUIFTFDPEFTJOUIF13 *OUSPEVDUJPOPG)BQQZ&ZFCBMMT7FSTJPO 3'$ JO4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 196

Slide 196 text

"OEUIJT13IBTCFFONFSHFEJOUPNBTUFSBOEUIF OFXWFSTJPOPG4PDLFUUDQXJMMCFJODMVEFE JO3VCZ .FSHFE

Slide 197

Slide 197 text

1MFBTFHJWF 4PDLFUUDQXJUI)&WTVQQPSUFEBUSZ *MPPLGPSXBSEUPIFBSJOHZPVSGFFECBDL

Slide 198

Slide 198 text

*TJUBIBQQJMZFWFSBGUFSʜ

Slide 199

Slide 199 text

8FNVTUOPUGPSHFU 5IF5$14PDLFUOFX JNQMFNFOUFEJO$ BMTPOFFET )BQQZ&ZFCBMMTTVQQPSU 5IJTIBTOPUCFFOJNQMFNFOUFE 1BHFPGTMJEFT

Slide 200

Slide 200 text

3FGIUUQTEBUBUSBDLFSJFUGPSHEPDESBGUQBVMZWPQTIBQQZFZFCBMMTW 4P UIJTJTDVSSFOUMZCFJOHXPSLFEPOBTXFMM *MMDPOUJOVFUPCFBCMFUPVQEBUFZPVXJUIGVSUIFS QSPHSFTT 5IFQBSUPGBDUVBMTPVSDFDPEFTPG5$14PDLFUOFX

Slide 201

Slide 201 text

5PCFDPOUJOVFE

Slide 202

Slide 202 text

5IBOLZPVGPSZPVSBUUFOUJPO 4QFDJBMUIBOLTUP FTQFDJBMMZ !OBSVTF !NNBTBLJ!BLS 3VCZDPNNJUUFST !PLVSBNBTBGVNJ BOE 5IF3VCZ"TTPDJBUJPO

Slide 203

Slide 203 text

'PSXIFOUIFEFNPEPFTOUXPSL

Slide 204

Slide 204 text

3VOOJOHUIFTFSWFSXJUIPVUPQUJPO XJUIPVUPQUJPO XJUI3VCZ )&WOPUTVQQPSUFE XJUI3VCZTVQQPSUFE)&W #PUIUIFWFSTJPOPG3VCZBOE3VCZXIJDITVQQPSUT )&WXJMMTVDDFTTGVMMZDPOOFDUJNNFEJBUFMZ 4FSWFS XJUIPVUBOZPCTUBDMFTUPDPOOFDUJWJUZ $MJFOU

Slide 205

Slide 205 text

3VOOJOHUIFTFSWFSXJUI*1WPQUJPO XJUI*1WPQUJPO XJUI3VCZTVQQPSUFE)&W #PUIUIFWFSTJPOPG3VCZBOE3VCZXIJDITVQQPSUT )&WXJMMTVDDFTTGVMMZDPOOFDUUPBO*1WBEESFTT JNNFEJBUFMZ 4FSWFS $POOFDUJPOTUP*1WBEESFTTFTBSFPCTUSVDUFE $MJFOU XJUI3VCZ )&WOPUTVQQPSUFE

Slide 206

Slide 206 text

3VOOJOHUIFTFSWFSXJUI*1WPQUJPO XJUI*1WPQUJPO 4FSWFS $POOFDUJPOTUP*1WBEESFTTFTBSFPCTUSVDUFE

Slide 207

Slide 207 text

3VOOJOHUIFTFSWFSXJUI*1WPQUJPO XJUI*1WPQUJPO 4FSWFS $POOFDUJPOTUP*1WBEESFTTFTBSFPCTUSVDUFE $MJFOU XJUI3VCZ )&WOPUTVQQPSUFE 3VCZDBOOPUNBLFBTVDDFTTGVMDPOOFDUJPOBUUFNQU BOEUIFQSPHSBNTUPQT )FSF $USM$JTVTFEUPGPSDFUIFQSPHSBNUPUFSNJOBUF

Slide 208

Slide 208 text

3VOOJOHUIFTFSWFSXJUI*1WPQUJPO XJUI*1WPQUJPO 4FSWFS $POOFDUJPOTUP*1WBEESFTTFTBSFPCTUSVDUFE $MJFOU XJUI3VCZ )&WOPUTVQQPSUFE )PXFWFS 3VCZXIJDITVQQPSUT)&WTVDDFTTGVMMZ DPOOFDUFEUPUIF*1WBEESFTTJOTUFBEPGUIF*1WBEESFTT JNNFEJBUFMZ