Slide 1

Slide 1 text

4PNFNPSFBEWFOUVSFPG)BQQZ&ZFCBMMT ԘҪඒ࡙ !TIJPJNN!DPF@   3VCZ,BJHJGPMMPXVQ

Slide 2

Slide 2 text

QQTFMG ɹԘҪඒ࡙ ͓͍͠  ɹ!TIJPJNN (JU)VC  ɹ!DPF@ 5XJUUFS !DPF #MVFTLZ  3VCZ,BJHJͰ ʮ"OBEWFOUVSFPG)BQQZ&ZFCBMMTʯͱ͍͏ ൃදΛ͠·ͨ͠

Slide 3

Slide 3 text

͜Ε·Ͱͷ͋Β͢͡ ͋Δͱ͜Ζʹ4PDLFUUDQͱ͍͏ϝιου͕ ࢦఆͷαʔόʔʹରͯ͠ɺ5$1Ͱ઀ଓͨ͠ΫϥΠΞϯτιέοτΛฦ͢ ιέοτίϯϐϡʔλʹͱͬͯͷ௨৴ͷग़ೖΓޱ ઀ଓ։࢝ ઀ଓ׬ྃ 4PDLFUUDQ αʔό

Slide 4

Slide 4 text

͜Ε·Ͱͷ͋Β͢͡ ઀ଓઌαʔό͕*1W*1WΞυϨε྆ํΛ࣋ͭ৔߹ɺ ैདྷͷ4PDLFUUDQ͸໊લղܾ΍઀ଓࢼߦΛʮ௚ྻʹʯߦ͏ ➡︎ ໊લղܾ΍઀ଓΛઌʹߦ͓͏ͱͨ͠ ɹΞυϨεϑΝϛϦͷ઀ଓੑ͕ѱ͍ͱɺ ɹޙଓͷॲཧ͕࣮ߦͰ͖ͳ͍ͱ͍͏՝୊͕͋ͬͨ *1W *1W ྫ 4PDLFUUDQ αʔό *1WѼʹ઀ଓ։࢝ *1WͰͷ઀ଓ͕׬ྃ͠ͳ͍ *1WѼͷ઀ଓΛ։࢝Ͱ͖ͳ͍

Slide 5

Slide 5 text

͜Ε·Ͱͷ͋Β͢͡ 3'$ʹͯɺ͜ͷ՝୊Λղܾ͢ΔͨΊͷΞϧΰϦζϜɺ )BQQZ&ZFCBMMT7FSTJPO )&W ͕نఆ͞Ε͍ͯΔ )&W͸໊લղܾ΍઀ଓࢼߦΛ ʮҰͭͣͭ௚ྻʹʯͰ͸ͳ͘ʮෳ਺ฒߦʹʯߦ͏͜ͱͰɺ ޮ཰Α͘઀ଓͰ͖ΔΑ͏ʹ͢Δɺͱ͍͏΋ͷ *1W *1W ྫ 4PDLFUUDQ αʔό *1WѼͷ઀ଓΛ։࢝ ͲͪΒ͔ૣ͍ํͰ઀ଓ͕׬ྃ *1WѼʹ઀ଓ։࢝

Slide 6

Slide 6 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W *1Wͱ*1Wͷ໊લղܾΛฒߦͯ྆͠ํಉ࣌ʹ։࢝͢Δ 4PDLFUUDQ Ѽઌαʔό %/4αʔό *1W໊લղܾ։࢝ *1W໊લղܾ։࢝ *1W *1W

Slide 7

Slide 7 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W ઌʹղܾͰ͖ͨΞυϨεѼʹ઀ଓΛ։࢝͢Δ 4PDLFUUDQ Ѽઌαʔό %/4αʔό *1W໊લղܾ։࢝ *1W໊લղܾ։࢝ *1W໊લղܾ׬ྃ *1WѼʹ઀ଓ։࢝ *1W *1W

Slide 8

Slide 8 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W ઌʹ*1Wͷ໊લղܾ͕׬ྃͨ͠৔߹ଈ࠲ʹ઀ଓΛ։࢝ͤͣ *1Wͷ໊લղܾΛNT଴ػ͢Δ 3FTPMVUJPO%FMBZ 4PDLFUUDQ Ѽઌαʔό %/4αʔό *1W໊લղܾ։࢝ *1W໊લղܾ։࢝ *1W໊લղܾ׬ྃ ͙͢ʹ઀ଓͤͣɺNT଴ػ 3FTPMVUJPO%FMBZ  *1W *1W )&WͰ͸*1WͰͷ઀ଓΛ༏ઌ͍ͨ͠ૂ͍͕͋ΔͨΊ

Slide 9

Slide 9 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W ղܾͨ͠ΞυϨεͷ͏ͪҰͭʹରͯ͠઀ଓΛ։࢝ͨ͠ޙɺ ઀ଓͷ׬ྃΛNT଴ػ͢Δ $POOFDUJPO"UUFNQU%FMBZ 4PDLFUUDQ Ѽઌαʔό ઀ଓͷ׬ྃΛNT଴ػ  $POOFDUJPO"UUFNQU%FMBZ ղܾࡁΈͷΞυϨε"Ѽʹ઀ଓ։࢝

Slide 10

Slide 10 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W NTҎ಺ʹҰͭ໨ͷ઀ଓ͕׬ྃ͠ͳ͔ͬͨ৔߹ɺ ଞͷղܾࡁΈͷΞυϨεѼʹೋͭ໨ͷ઀ଓΛ։࢝͢Δ 4PDLFUUDQ Ѽઌαʔό ղܾࡁΈͷΞυϨε"Ѽʹ઀ଓ։࢝ NTޙɺผͷΞυϨε#Ѽʹ઀ଓ։࢝ ˞Ҏ߱ɺ઀ଓʹ੒ޭ͢Δ·Ͱɺ·ͨ͸ ɹΞυϨεͷࡏݿ͕ਚ͖Δ·Ͱ ɹNT͝ͱʹ৽͍͠઀ଓΛ։࢝͢Δ

Slide 11

Slide 11 text

͜Ε·Ͱͷ͋Β͢͡෼ͰΘ͔Δ)&W ͍ͣΕ͔ͷ઀ଓ͕੒ޭͨ͠Βɺ੒ޭͨ͠઀ଓҎ֎͸ Ωϟϯηϧ͢Δ 4PDLFUUDQ Ѽઌαʔό ղܾࡁΈͷΞυϨε"Ѽʹ઀ଓ։࢝ #Ѽͷ઀ଓ͕׬ྃ NTޙɺผͷΞυϨε#Ѽʹ઀ଓ։࢝ "Ѽͷ઀ଓ͸Ωϟϯηϧ

Slide 12

Slide 12 text

͜Ε·Ͱͷ͋Β͢͡ঢ়ଶભҠͰ͋ΒΘ͢)&W WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU )&Wͷಈ࡞ϑϩʔΛදݱ͢ΔԼهͷΑ͏ͳঢ়ଶભҠਤΛ࡞੒͠ ͜ΕΛϕʔεʹ4PDLFUUDQͷ)&W࣮૷Λߦͳͬͨ ʜ֤ঢ়ଶ ʜঢ়ଶͷભҠ

Slide 13

Slide 13 text

͜Ε·Ͱͷ͋Β͢͡)&Wͷঢ়ଶભҠ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ઌʹ*1WΛղܾ ઌʹ*1WΛղܾ ʜݩͷঢ়ଶ ʜભҠઌͷঢ়ଶ TUBSU։࢝࣌఺Ͱͷঢ়ଶɻ*1Wͱ*1Wͷ໊લղܾΛಉ࣌ʹ։࢝͢Δ ͲͪΒ͔͕׬ྃ͢Δ·Ͱ଴ػ͢Δ

Slide 14

Slide 14 text

͜Ε·Ͱͷ͋Β͢͡)&Wͷঢ়ଶભҠ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ࣌ؒ಺ʹ*1Wͷ໊લղܾ׬ྃͤͣ ࣌ؒ಺ʹ*1Wͷ໊લղܾ׬ྃ WX*1Wͷ໊લղܾΛNT଴ػ 3FTPMVUJPO%FMBZ

Slide 15

Slide 15 text

͜Ε·Ͱͷ͋Β͢͡)&Wͷঢ়ଶભҠ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ˞͍ͣΕͷঢ়ଶ΋઀ଓ։࢝ޙ͸WX΁ભҠͯ͠઀ଓΛ଴ػ WD*1WΞυϨεѼʹ઀ଓ։࢝WD*1WΞυϨεѼʹ઀ଓ։࢝ WD*1WΞυϨε·ͨ͸*1WΞυϨεѼʹ઀ଓ։࢝

Slide 16

Slide 16 text

͜Ε·Ͱͷ͋Β͢͡)&Wͷঢ়ଶભҠ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU ଴ػͷϦτϥΠ ೋճ໨Ҏ߱ͷ઀ଓ։࢝Մೳ WX઀ଓͷ׬ྃ·ͨ͸໊લղܾͷ׬ྃΛNT଴ػ  $POOFDUJPO"UUFNQU%FMBZ ͢΂ͯͷ໊લղܾ͔઀ଓʹࣦഊ ϢʔβʔࢦఆͷλΠϜΞ΢τ͕ൃੜ ઀ଓʹ੒ޭ

Slide 17

Slide 17 text

͜Ε·Ͱͷ͋Β͢͡)&Wͷঢ়ଶભҠ WD GBJMVSF WX TVDDFTT WD WD TUBSU WX UJNFPVU TVDDFTTGBJMVSFUJNFPVUऴྃঢ়ଶ

Slide 18

Slide 18 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then when :v4w then when :v6c, :v4c, :v46c then when :v46w then when :success then when :failure then when :timeout then end end end ͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ શମ૾ ໊લղܾΛ։࢝͢Δ IPv6ͷ໊લղܾ׬ྃΛ50ms଴ػ͢Δ ઀ଓΛ։࢝͢Δ ઀ଓঢ়ଶͷ֬ఆͱ໊લղܾͷ׬ྃΛ଴ػ͢Δ ઀ଓʹ੒ޭͨ͠ιέοτΛฦ͢ ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τྫ֎Λൃੜͤ͞Δ ࣮૷ʹ͋ͨͬͯ͸,FSOFMMPPQͱDBTFΛ ૊Έ߹ΘͤΔ͜ͱͰઌ΄Ͳͷঢ়ଶભҠΛදݱ͢Δ

Slide 19

Slide 19 text

def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then when :v4w then when :v6c, :v4c, :v46c then when :v46w then when :success then when :failure then when :timeout then end end end ͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ શମ૾ ໊લղܾΛ։࢝͢Δ IPv6ͷ໊લղܾ׬ྃΛ50ms଴ػ͢Δ ઀ଓΛ։࢝͢Δ ઀ଓঢ়ଶͷ֬ఆͱ໊લղܾͷ׬ྃΛ଴ػ͢Δ ઀ଓʹ੒ޭͨ͠ιέοτΛฦ͢ ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τྫ֎Λൃੜͤ͞Δ ϧʔϓ಺Ͱ͸ඞͣʮݱࡏͷঢ়ଶʯ͕ઃఆ͞Ε͍ͯΔɻ ঢ়ଶʹԠͯ͡ߦ͏΂͖ॲཧΛ࣮ߦ͠ɺ ࣍ͷঢ়ଶΛઃఆ͠ɺ࣍ͷϧʔϓʹਐΉ ֤ঢ়ଶͰߦ͏ॲཧ TUBUFʮݱࡏͷঢ়ଶʯΛ؅ཧ͢Δม਺ ॳظঢ়ଶͱͯ͠TUBSUΛઃఆ  ݱࡏͷঢ়ଶ

Slide 20

Slide 20 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 } ) # ... ͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ TUBSU TUBSUΞυϨεϑΝϛϦ͝ͱʹεϨουΛੜ੒ɻ ͦΕͧΕͷࢠεϨουͰ໊લղܾ༻ͷϝιουΛ ݺͼग़͢͜ͱʹΑΓɺ*1W*1Wͷ໊લղܾΛ ฒߦʹ։࢝͢Δɻ hostname_resolution_args = [host, port, hostname_resolution_queue] ֤ࢠεϨουͰ໊લղܾϝιουΛ࣮ߦ ΞυϨεϑΝϛϦ͝ͱʹεϨουΛ࡞੒ ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ

Slide 21

Slide 21 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) ͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ TUBSU TUBSU*0TFMFDUΛ༻໊͍ͯલղܾ͕׬ྃ͢Δ·Ͱ  جຊతʹ͸ ແظݶͰ଴ػ͢Δ ͲͪΒ͔ͷ໊લղܾ͕׬ྃ͢Δ·ͰॲཧΛϒϩοΫ ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ ϢʔβʔࢦఆͷλΠϜΞ΢τ஋ ࢦఆ͕ͳ͍৔߹͸OJMແظݶ ࣍ͷঢ়ଶΛܾఆ ࣍ͷঢ়ଶ΁ ໊લղܾͷ݁ՌΛऔಘ

Slide 22

Slide 22 text

͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ WX 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*0TFMFDUΛ༻͍ͯ*1Wͷ໊લղܾΛNT଴ػɻ ଴ػ࣌ؒ಺ʹ*1Wͷ໊લղܾ͕׬͔ྃͨ͠ʹΑͬͯɺ ࣍ͷঢ়ଶΛ൑அ͢Δɻ (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) ˞ઌʹ*1WΛղܾͰ͖ͨ৔߹ʹ*1Wͷ໊લղܾΛ଴ػ͢ΔͨΊͷঢ়ଶ Exception NT ࣍ͷঢ়ଶ΁ ࣍ͷঢ়ଶΛܾఆ *1Wͷ໊લղܾ͕׬ྃ͢Δ͔λΠϜΞ΢τ͢Δ·ͰॲཧΛϒϩοΫ

Slide 23

Slide 23 text

͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ WDWDWD 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) WDWDWDղܾࡁΈͷΞυϨεΛͻͱͭऔಘ͠ɺ ϊϯϒϩοΩϯάϞʔυͰ઀ଓΛ։࢝ɻ ઀ଓ͠ʹཁͨ͠ιέοτΛอଘͯ͠WX΁ભҠ ˞઀ଓΛ։࢝͢ΔͨΊͷঢ়ଶ औಘࡁΈͷΞυϨεΛҰͭऔಘ ઀ଓΛ։࢝ ࣍ͷঢ়ଶ΁ ࣍ͷঢ়ଶΛηοτ ઀ଓʹ࢖༻ͨ͠ιέοτΛอଘ

Slide 24

Slide 24 text

͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ WX 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) WX*0TFMFDUΛ༻͍ͯ઀ଓঢ়ଶͷ֬ఆ͔ ໊લղܾͷ׬ྃΛNT଴ػɻ*0TFMFDUͷ݁Ռ ൃੜͨ͠ΠϕϯτͳͲʹΑͬͯɺ࣍ͷঢ়ଶΛ൑அ͢Δ ˞઀ଓঢ়ଶͷ֬ఆͱ໊લղܾͷ׬ྃΛಉ࣌ʹ଴ػ͢ΔͨΊͷঢ়ଶ NT ࣍ͷঢ়ଶ΁ ࣍ͷঢ়ଶΛܾఆ  ઀ଓঢ়ଶ͕֬ఆ  ໊લղܾ͕׬ྃ $POOFDUJPO"UUFNQU%FMBZ͕λΠϜΞ΢τ ઀ଓঢ়ଶ͕֬ఆ͢Δ͔ɺ໊લղܾ͕׬ྃ͢Δ͔ɺ λΠϜΞ΢τ͢Δ·ͰॲཧΛϒϩοΫ

Slide 25

Slide 25 text

͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ ऴྃঢ়ଶ case state when :success break connected_socket when :failure raise last_error when :timeout raise Errno::ETIMEDOUT, "user specified timeout" end TVDDFTT ➡︎ ઀ଓʹ੒ޭͨ͠ιέοτΛฦ͢ GBJMVSF ➡︎ ࠷ޙʹิ଍ͨ͠ΤϥʔͰྫ֎Λൃੜͤ͞Δ UJNFPVU ➡︎ λΠϜΞ΢τΛද͢ྫ֎Λൃੜͤ͞Δ ˞઀ଓʹ੒ޭͨ͠ιέοτΛฦͨ͢Ίͷঢ়ଶ ˞͢΂ͯͷ໊લղܾͱ઀ଓʹࣦഊ͠ɺྫ֎Λൃੜͤ͞ΔͨΊͷঢ়ଶ ˞ϢʔβʔࢦఆͷλΠϜΞ΢τ͕ൃੜ͠ɺྫ֎Λൃੜͤ͞ΔͨΊͷঢ়ଶ

Slide 26

Slide 26 text

͜Ε·Ͱͷ͋Β͢͡4PDLFUUDQͷ࣮૷ def self.tcp(host, port, ...) # ... state = :start loop do case state when :start then when :v4w then when :v6c, :v4c, :v46c then when :v46w then when :success then when :failure then when :timeout then end end end ׬੒ ໊લղܾΛ։࢝͢Δ IPv6ͷ໊લղܾ׬ྃΛ଴ػ͢Δ ઀ଓΛ։࢝͢Δ ઀ଓঢ়ଶͷ֬ఆͱ໊લղܾͷ׬ྃΛ଴ػ͢Δ ઀ଓʹ੒ޭͨ͠ιέοτΛฦ͢ ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τྫ֎Λൃੜͤ͞Δ

Slide 27

Slide 27 text

ΊͰͨ͠ΊͰͨ͠

Slide 28

Slide 28 text

ΊͰͨ͠ΊͰͨ͠ Ͱ͸ͳ͔ͬͨ

Slide 29

Slide 29 text

Ͱ͸ͳ͔ͬͨ ࣮૷Λঢ়ଶભҠʹدͤ͗͢Ͱ͸ BLS͞Μ

Slide 30

Slide 30 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) ઌʹղܾͰ͖ͨΞυϨεϑΝϛϦʹΑͬͯ࣍ͷঢ়ଶΛܾఆ ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ TUBSUઌʹ໊લղܾ͕׬ྃͨ͠ͷ͕*1Wͩͬͨͷ͔ɺ *1Wͩͬͨͷ͔ʹΑͬͯɺ࣍ͷঢ়ଶΛ൑அ͍ͯ͠Δ ʮ࣮૷Λঢ়ଶભҠʹدͤ͗͢ʯͷྫTUBSU ໊લղܾͷ݁ՌΛऔಘ

Slide 31

Slide 31 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) ͜ͷ࣌఺Ͱ*1W*1Wͱ΋ʹ ໊લղܾ͕׬͍ྃͯͨ͠ΒͲ͏ͳΔ   ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ ʮ࣮૷Λঢ়ଶભҠʹدͤ͗͢ʯͷྫTUBSU

Slide 32

Slide 32 text

εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ ࢠεϨου͸໊લղܾ͕׬ྃͨ͠ޙɺͦͷ݁Ռͱͯ͠ ղܾͨ͠ΞυϨεϑΝϛϦ໊ͱऔಘͨ͠ΞυϨεΛ ཁૉʹ࣋ͭ഑ྻΛϝΠϯεϨουʹड͚౉͢ ϝΠϯεϨου *1W໊લղܾεϨου *1W໊લղܾεϨου ˞ʮࢠεϨου໊͕લղܾ͠ɺϝΠϯεϨου͕ͦΕΛ଴ػ͢Δʯͱ͍͏ॲཧͷཪଆ [:ipv4, ["127.0.0.1", ...]]

Slide 33

Slide 33 text

εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ ड͚౉͠͸ɺϝΠϯεϨουࢠεϨουؒͰ ڞ༗͍ͯ͠ΔΩϡʔΛհͯ͠ߦΘΕΔ ϝΠϯεϨου ڞ༗Ωϡʔ *1W໊લղܾεϨου *1W໊લղܾεϨου

Slide 34

Slide 34 text

ϝΠϯεϨου͸*0TFMFDUͰ໊લղܾΛ଴ػ͢Δ ڞ༗Ωϡʔ ϝΠϯεϨου *1W໊લղܾεϨου *1W໊લղܾεϨου εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ *0TFMFDUͰ଴ػதʜ *1W໊લղܾதʜ *1W໊લղܾதʜ

Slide 35

Slide 35 text

ࢠεϨου͸໊લղܾ͕ऴΘΓ࣍ୈɺ ݁ՌΛΩϡʔʹQVTI͢Δ ·ͨɺϝΠϯεϨουͷ*0TFMFDUʹ׬ྃΛ௨஌͢Δ ڞ༗Ωϡʔ *1Wͷ໊લղܾ͕ऴΘͬͨ ϝΠϯεϨου *1W໊લղܾεϨου *1W໊લղܾεϨου εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ *0TFMFDUͰ଴ػதʜ ݁ՌΛQVTI ໊લղܾͷ׬ྃΛ௨஌

Slide 36

Slide 36 text

ϝΠϯεϨου͸*0TFMFDUʹ௨஌Λड͚औΔͱɺ ଴ػΛղআͯ͠Ωϡʔ͔Β݁ՌΛQPQ͢Δ ڞ༗Ωϡʔ ݁ՌΛQPQ ϝΠϯεϨου *1W໊લղܾεϨου *1W໊લղܾεϨου εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ *0TFMFDUͷ଴ػΛղআ

Slide 37

Slide 37 text

 ྫ  ઌʹยํͷࢠεϨουͰ*1Wͷ໊લղܾ͕׬ྃͯ͠ Ωϡʔʹ݁Ռ͕QVTI͞Εͨޙɺ ϝΠϯεϨου ڞ༗Ωϡʔ *1Wͷ໊લղܾ͕ऴΘͬͨ *1W໊લղܾεϨου *1W໊લղܾεϨου εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ ݁ՌΛQVTI ໊લղܾͷ׬ྃΛ௨஌

Slide 38

Slide 38 text

ϝΠϯεϨου͕ͦΕΛQPQ͢Δલʹɺ ΋͏ยํͷࢠεϨουͰ*1Wͷ໊લղܾ͕׬ྃ͠ɺ Ωϡʔʹ*1Wͷ໊લղܾ݁Ռ΋QVTI͞Εͨ৔߹ *1W໊લղܾεϨου ڞ༗Ωϡʔ ݁ՌΛQVTI ϝΠϯεϨου *1W໊લղܾεϨου εϨουؒͰͷΞυϨεͷड͚౉͠ͷ࢓૊Έ ·ͩΩϡʔ͔ΒQPQ͍ͯ͠ͳ͍ ໊લղܾͷ׬ྃΛ௨஌ *1Wͷ໊લղܾ͕ऴΘͬͨ

Slide 39

Slide 39 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 ʮ࣮૷Λঢ়ଶભҠʹدͤ͗͢ʯͷྫTUBSU ϝΠϯεϨου͸*0TFMFDUͷ଴ػΛղআ͠ɺΩϡʔͷ ઌ಄͔Βͻͱͭऔಘ͢Δ ઌ಄͸*1Wͷ໊લղܾ݁Ռ  ϝΠϯεϨου͸औಘͰ͖ͨΞυϨεϑΝϛϦ͔Β ࣍ͷঢ়ଶΛ൑அ͢ΔͨΊɺ͜ͷ৔߹͸WX΁ભҠ͢Δɻ (hostname_resolution_waiting, nil, nil, remaining) Ωϡʔͷઌ಄Λऔಘ औಘͨ͠ΞυϨεϑΝϛϦ͕*1WͳͷͰɺ ࣍ͷঢ়ଶΛWXͱ൑அͯ͠͠·͏ ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ

Slide 40

Slide 40 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 ˞ઌʹ*1WΛղܾͰ͖ͨ৔߹ʹ*1Wͷ໊લղܾΛ଴ػ͢ΔͨΊͷঢ়ଶ WXʹͯɺ*1W͸͢ͰʹղܾࡁΈͰ͋Δʹ΋ؔΘΒͣ *1Wͷ໊લղܾΛ଴ػ͢ΔͨΊʹ*0TFMFDUΛݺͼग़͢  ෆཁͳ*0TFMFDUͷݺͼग़͕͠ൃੜ͍ͯ͠Δ ͢Ͱʹ*1W͸ղܾࡁΈͳͷʹɺෆཁʹ*0TFMFDUΛݺͼग़͍ͯ͠Δ (hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) ʮ࣮૷Λঢ়ଶભҠʹدͤ͗͢ʯͷྫWX Ωϡʔͷઌ಄Λऔಘ Exception

Slide 41

Slide 41 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 # ... next (hostname_resolution_waiting, nil, nil, remaining) ঢ়ଶભҠΛݟͨ໨ͷ··࣮૷ͨ݁͠ՌɺҰͭͷঢ়ଶ͔Β͸ ඞͣҰͭͷঢ়ଶ΁ભҠ͢Δͱ͍͏લఏͷ࣮૷ʹͳ͍ͬͯΔɻ Ұํɺ࣮ࡍʹ͸͜ͷྫͷΑ͏ʹʮঢ়ଶͷॏͶ߹Θͤʯ͕ ൃੜ͠͏Δɻ TUBSU͔ΒWDʹભҠ͢ΔͨΊͷ৚݅ͱ WXʹભҠ͢ΔͨΊͷ৚͕݅ಉ࣌ʹຬͨ͞Ε͏Δ Ұͭͷঢ়ଶ͔Β͸ඞͣҰͭͷঢ়ଶ΁ભҠ͢Δ  ʮঢ়ଶͷॏͶ߹Θͤʯ͕ൃੜ͢ΔՄೳੑ͕ ߟྀ͞Ε͍ͯͳ͍ ˞໊લղܾΛ։࢝͢ΔͨΊͷঢ়ଶ

Slide 42

Slide 42 text

໰୊఺ͷ੔ཧ ݱࡏͷ࣮૷ͷલఏ ɹɹ࣮ߦத͸ʮݱࡏͷঢ়ଶʯΛ؅ཧ͢Δ ɹɹʮঢ়ଶʯ͝ͱʹߦ͏΂͖ॲཧ͕ܾ·͍ͬͯΔ ɹɹҰϧʔϓͷதͰҰͭͷʮঢ়ଶʯΛදݱ͢Δ ɹɹɹ ͦͷʮঢ়ଶʯͰߦ͏΂͖ॲཧΛߦ͏ɻ ɹɹɹ࣍ͷʮঢ়ଶʯΛηοτͯ࣍͠ͷϧʔϓʹೖΔ

Slide 43

Slide 43 text

໰୊఺ͷ੔ཧ ݱࡏͷ࣮૷ͷ໰୊ ɹɹʮঢ়ଶͷॏͶ߹Θͤʯ͕ൃੜͨ͠৔߹ɺ ɹɹɹॏͳͬͨঢ়ଶBCͷ͏ͪͻͱͭBΛબ୒ͯ͠ભҠ͢Δ

Slide 44

Slide 44 text

໰୊఺ͷ੔ཧ ݱࡏͷ࣮૷ͷ໰୊ ɹɹʮঢ়ଶͷॏͶ߹Θͤʯ͕ൃੜͨ͠৔߹ɺ ɹɹɹॏͳͬͨঢ়ଶBCͷ͏ͪͻͱͭBΛબ୒ͯ͠ભҠ͢Δ ɹɹ ➡︎ ࣍ͷϧʔϓͰ͸ঢ়ଶBͰߦ͏΂͖ॲཧ͚͕࣮ͩߦ͞Εɺ ɹɹɹબ୒͞Εͳ͔ͬͨঢ়ଶCͰߦ͏ॲཧ͕࢒Δ

Slide 45

Slide 45 text

໰୊఺ͷ੔ཧ ݱࡏͷ࣮૷ͷ໰୊ ɹɹʮঢ়ଶͷॏͶ߹Θͤʯ͕ൃੜͨ͠৔߹ɺ ɹɹɹॏͳͬͨঢ়ଶBCͷ͏ͪͻͱͭBΛબ୒ͯ͠ભҠ͢Δ ɹɹ ➡︎ ࣍ͷϧʔϓͰ͸ঢ়ଶBͰߦ͏΂͖ॲཧ͚͕࣮ͩߦ͞Εɺ ɹɹɹબ୒͞Εͳ͔ͬͨঢ়ଶCͰߦ͏ॲཧ͕࢒Δ ɹɹ ➡︎ ݁Ռɺޡͬͨঢ়ଶʹભҠͨ͠Γɺ ɹɹɹͦͷઌͰෆཁͳ*0TFMFDUͷݺͼग़͕͠ൃੜ͢Δ

Slide 46

Slide 46 text

໰୊఺ͷ੔ཧ ݱࡏͷ࣮૷ͷ໰୊ ɹɹʮঢ়ଶͷॏͶ߹Θͤʯ͕ൃੜͨ͠৔߹ɺ ɹɹɹॏͳͬͨঢ়ଶBCͷ͏ͪͻͱͭBΛબ୒ͯ͠ભҠ͢Δ ɹɹ ➡︎ ࣍ͷϧʔϓͰ͸ঢ়ଶBͰߦ͏΂͖ॲཧ͚͕࣮ͩߦ͞Εɺ ɹɹɹબ୒͞Εͳ͔ͬͨঢ়ଶCͰߦ͏ॲཧ͕࢒Δ ɹɹ ➡︎ ݁Ռɺޡͬͨঢ়ଶʹભҠͨ͠Γɺ ɹɹɹͦͷઌͰෆཁͳ*0TFMFDUͷݺͼग़͕͠ൃੜ͢Δ ࣮૷͕ঢ়ଶભҠʹدΓա͍͗ͯΔ

Slide 47

Slide 47 text

ݩͷ࣮૷ *OUSPEVDUJPOPG)BQQZ&ZFCBMMT7FSTJPO 3'$  JO4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 48

Slide 48 text

ݩͷ࣮૷ *OUSPEVDUJPOPG)BQQZ&ZFCBMMT7FSTJPO 3'$  JO4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM ͍ͬͨΜແ͠

Slide 49

Slide 49 text

͔Β࠶࣮૷ *NQSPWF4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM

Slide 50

Slide 50 text

)&WରԠ4PDLFUUDQ վ ݩͷ࣮૷ίϯηϓτ ࠶ܝ  ɹɹ࣮ߦத͸ʮݱࡏͷঢ়ଶʯΛ؅ཧ͢Δ ɹɹʮঢ়ଶʯ͝ͱʹߦ͏΂͖ॲཧ͕ܾ·͍ͬͯΔ ɹɹҰϧʔϓͷதͰҰͭͷʮঢ়ଶʯΛදݱ͢Δ ▫՝୊ ҰճͷϧʔϓͷதͰҰͭͷঢ়ଶ͔͠දݱͰ͖ͳ͍ ➡︎ ͦͷϧʔϓͷதͰ·ͩߦ͏͜ͱ͕Ͱ͖Δॲཧ͕࢒͍ͬͯͯ΋ ɹͦΕΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖ͳ͍

Slide 51

Slide 51 text

)&WରԠ4PDLFUUDQ վ վળޙͷ࣮૷ίϯηϓτ ɹɹʮݱࡏͷঢ়ଶʯΛ؅ཧ͠ͳ͍ ɹɹҰϧʔϓͷதͰߦ͏͜ͱ͕Ͱ͖Δॲཧ͸͢΂ͯߦ͏

Slide 52

Slide 52 text

)&WରԠ4PDLFUUDQ վ ͷ֓؍ def self.tcp(host, port, ...) loop do end end ໊લղܾͷ։࢝ if ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ then ઀ଓΛ։࢝ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>) if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖ͳ͍ then ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τม਺ͷॳظԽ

Slide 53

Slide 53 text

def self.tcp(host, port, ...) loop do end end ໊લղܾͷ։࢝ if ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ then ઀ଓΛ։࢝ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>) if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖ͳ͍ then ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τม਺ͷॳظԽ )&WରԠ4PDLFUUDQ վ ͷ֓؍ ϧʔϓͷͨͼʹ্͔Βॱʹ࣮ߦ͞ΕΔ ঢ়ଶ؅ཧΛ΍Ίͨ͜ͱʹΑΓϧʔϓ಺ͷDBTF͕ফ͑ ୅ΘΓʹJGจʹΑΔ৚݅෼ذ͕௥Ճ͞Ε͍ͯΔ

Slide 54

Slide 54 text

)&WରԠ4PDLFUUDQ վ ͷ࣮૷ϧʔϓʹೖΔલ def self.tcp(host, port, ...) # ... resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil # ... loop do # ... end end λΠϜΞ΢τΛ؅ཧ͢Δม਺ ϧʔϓʹೖΔલᶃ ৽ͨʹλΠϜΞ΢τΛ؅ཧ͢Δม਺Λ༻ҙɻ ͦΕͧΕʹॳظ஋ͱͯ͠OJMΛηοτ͢Δ ϧʔϓΛ։࢝  SFTPMVUJPO@EFMBZ@FYQJSFT@BU *1Wͷ໊લղܾΛNT଴ػ͢ΔͨΊͷ࣌ؒ 3FTPMVUJPO%FMBZ Λ֨ೲ͢Δม਺ DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BU ࣍ͷ઀ଓͷ։࢝·ͰNT଴ػ͢ΔͨΊͷ࣌ؒ $POOFDUJPO"UUFNQU%FMBZ Λ֨ೲ͢Δม਺

Slide 55

Slide 55 text

def self.tcp(host, port, ...) # ... resolution_delay_expires_at = nil connection_attempt_delay_expires_at = nil # ... loop do # ... end end )&WରԠ4PDLFUUDQ վ ͷ࣮૷ϧʔϓʹೖΔલ λΠϜΞ΢τΛ؅ཧ͢Δม਺  ˞͜ΕΒͷม਺ʹ͸ͦΕͧΕɺ ɾλΠϜΞ΢τΛ଴ͭॲཧ͕ൃੜͨ͠ࡍʹʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯͷ͕࣌ؒηοτ͞ΕΔ ɾηοτ͕ͨ࣌ؒ͠ݱࡏ࣌ࠁΑΓ΋աڈ࣌ؒʹͳͬͨΓ଴ػ͕ෆཁʹͳΔͱOJM͕ηοτ͞ΕΔ ϧʔϓΛ։࢝

Slide 56

Slide 56 text

)&WରԠ4PDLFUUDQ վ ͷ࣮૷ϧʔϓʹೖΔલ def self.tcp(host, port, ...) # ... hostname_resolution_threads.concat( resolving_family_names.map { |family| th_args = [family, host, port, hostname_resolution_result] thread = Thread.new(*th_args) { |*th_args | resolve_hostname(*th_args) } Thread.pass thread } ) # ... loop do # ... end end ϧʔϓʹೖΔલᶄ໊લղܾΛฒߦʹ։࢝͢Δ  มߋલ͸ϧʔϓͷத TUBSU Ͱߦͳ͍͕ͬͯͨɺ ࣮ࡍʹ͸શମͰҰճ͔͠ߦΘͳ͍ॲཧͷͨΊ͜͜ʹҠಈ ΞυϨεϑΝϛϦ͝ͱʹεϨουΛੜ੒໊ͯ͠લղܾΛ։࢝ ϧʔϓΛ։࢝

Slide 57

Slide 57 text

def self.tcp(host, port, ...) # ... loop do # ... end end )&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓͷ։࢝ ໊લղܾͷ։࢝ λΠϜΞ΢τม਺ͷॳظԽ ϧʔϓΛ։࢝ ଓ͍ͯɺϧʔϓʹೖΔ

Slide 58

Slide 58 text

)&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓͷ։࢝ loop do if resolution_store.any_addrinfos? && !resolution_delay_expires_at && !connection_attempt_delay_expires_at while (addrinfo = resolution_store.get_addrinfo) # end # ... end end ϧʔϓͷதͰ͸·ͣ ʮ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ͔Ͳ͏͔ʯΛ֬ೝ͢Δ ɾղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δ͜ͱ ɾ͔ͭ*1Wͷ໊લղܾΛ଴ػதͰ͸ͳ͍͜ͱ ɾ͔ͭ઀ଓ։࢝ͷ଴ػதͰ͸ͳ͍͜ͱ ઀ଓΛ։࢝͢ΔͨΊͷॲཧ ϧʔϓΛ։࢝ ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ 

Slide 59

Slide 59 text

loop do # ... 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 # ... # ... end end # ... end ৚݅Λຬͨ͢৔߹ɺղܾࡁΈͷΞυϨεΛҰͭऔಘ͠ɺ ϊϯϒϩοΩϯάϞʔυͰ઀ଓΛ։࢝ ΞυϨεΛऔಘ ઀ଓΛ։࢝ )&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓͷ։࢝

Slide 60

Slide 60 text

loop do # ... 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 DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUʹ ࣍ͷ઀ଓ։࢝·ͰͷλΠϜΞ΢τ࣌ؒΛηοτ͢Δ ݱࡏ࣌ࠁͷNTޙΛηοτ )&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓͷ։࢝

Slide 61

Slide 61 text

loop do # ... 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 ઀ଓʹ࢖ͬͨιέοτΛอଘͨ͠Βɺ͜ͷJGจΛൈ͚Δ )&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓͷ։࢝ ઀ଓʹ࢖༻ͨ͠ιέοτΛอଘ

Slide 62

Slide 62 text

loop do # ... 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 )&WରԠ4PDLFUUDQ վ ͷ࣮૷໊લղܾͱ઀ଓͷ଴ػ ઀ଓঢ়ଶͷ֬ఆ·ͨ͸໊લղܾͷ׬ྃΛ଴ػ ଓ͍ͯɺ*0TFMFDUΛ༻͍ͯ઀ଓঢ়ଶͷ֬ఆ͔ ໊લղܾͷ׬ྃΛ଴ػ͢Δ  มߋલͷ4PDLFUUDQͷWXͰߦ͍ͬͯͨॲཧͱಉ͡ if ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ then ઀ଓΛ։࢝ if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ

Slide 63

Slide 63 text

)&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓঢ়ଶͷ֬ೝ loop do # ... 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 # ... end *0TFMFDU͕଴ػΛղআͨ͠Βɺ࣮ߦ݁Ռͱͯ͠ ʮ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ͔Ͳ͏͔ʯΛ֬ೝ ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ  IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>)

Slide 64

Slide 64 text

)&WରԠ4PDLFUUDQ վ ͷ࣮૷઀ଓঢ়ଶͷ֬ೝ loop do # ... 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 # ... end ৚͕݅ຬͨ͞Ε͍ͯΔ৔߹͸ɺର৅ͷιέοτͷ ઀ଓঢ়ଶΛ֬ೝ͠ɺద੾ͳॲཧΛߦ͏ ઀ଓʹ੒ޭ͍ͯ͠Δ  ઀ଓͰ͖ͨιέοτΛฦ͢ ઀ଓঢ়ଶͷ֬ೝ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>)

Slide 65

Slide 65 text

loop do # ... 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 # ... end ͞Βʹ*0TFMFDUͷ࣮ߦ݁Ռͱͯ͠ ʮ໊લղܾ͕׬͍ྃͯ͠Δ͔Ͳ͏͔ʯΛ֬ೝ )&WରԠ4PDLFUUDQ վ ͷ࣮૷໊લղܾͷ׬ྃ ໊લղܾ͕׬ྃͨ͠  IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>)

Slide 66

Slide 66 text

loop do # ... 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 # ... end ৚͕݅ຬͨ͞Ε͍ͯΕ͹ɺղܾͨ͠ΞυϨεΛ औಘͰ͖Δ͔͗Γऔಘͯ͠อଘ͢Δɻ )&WରԠ4PDLFUUDQ վ ͷ࣮૷໊લղܾͷ׬ྃ ΞυϨεΛऔಘͰ͖ΔݶΓऔಘ औಘͰ͖ͨΞυϨεΛอଘ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>)

Slide 67

Slide 67 text

loop do # ... if hostname_resolved&.any? while (family_and_result = hostname_resolution_result.get) # ... if resolution_store.resolved?(:ipv4) if resolution_store.resolved?(:ipv6) hostname_resolution_notifier = nil # ... user_specified_resolv_timeout_at = nil elsif resolution_store.resolved_successfully?(:ipv4) resolution_delay_expires_at = now + RESOLUTION_DELAY end end end end # ... end *1Wͷ໊લղܾ͕׬͓ྃͯ͠Γɺ͔ͭ*1Wͷ໊લղܾ͕ ׬͍ྃͯ͠ͳ͍৔߹͸SFTPMVUJPO@EFMBZ@FYQJSFT@BUʹ *1Wͷ໊લղܾΛ଴ػ͢Δ࣌ؒΛηοτ͢Δ )&WରԠ4PDLFUUDQ վ ͷ࣮૷໊લղܾͷ׬ྃ *1Wͷ໊લղܾ͕׬ྃͨ͠  ͔ͭɺ*1Wͷ໊લղܾ͕׬͍ྃͯ͠ͳ͍ ݱࡏ࣌ࠁͷNTޙΛηοτ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>)

Slide 68

Slide 68 text

loop do # ... if hostname_resolved&.any? while (family_and_result = hostname_resolution_result.get) # ... 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 end # ... end *1W*1Wͱ΋ʹ໊લղܾ͕׬͍ྃͯ͠Δ৔߹͸ SFTPMVUJPO@EFMBZ@FYQJSFT@BUʹOJMΛηοτ͢Δ )&WରԠ4PDLFUUDQ վ ͷ࣮૷໊લղܾͷ׬ྃ *1Wͷ໊લղܾ͕׬ྃͨ͠  ͔ͭɺ*1Wͷ໊લղܾ͕׬ྃͨ͠ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>) OJMΛηοτ

Slide 69

Slide 69 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 ϧʔϓͷ࠷ޙʹɺ ʮ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖Δ͔Ͳ͏͔ʯ֬ೝ )&WରԠ4PDLFUUDQ վ ͷ࣮૷࣍ͷϧʔϓ΁ ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖Δ  if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn)

Slide 70

Slide 70 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 ɾղܾࡁΈͷΞυϨεͷࡏݿ͕ͳ͍ ɾ͔ͭɺ઀ଓதͷιέοτ͕ͳ͍ ɾ͔ͭɺ͢΂ͯͷ໊લղܾ͕ऴΘ͍ͬͯΔ৔߹͸ ͜ΕҎ্࣮ߦͰ͖Δॲཧ͕ͳ͍ͨΊɺྫ֎Λൃੜͤ͞Δ )&WରԠ4PDLFUUDQ վ ͷ࣮૷࣍ͷϧʔϓ΁ if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) ͜ΕҎ্࣮ߦͰ͖Δॲཧ͕ͳ͍  ࠷ޙʹิ଍ͨ͠ΤϥʔͰྫ֎Λൃੜͤ͞Δ

Slide 71

Slide 71 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 ϢʔβʔࢦఆͷλΠϜΞ΢τ͕௒ա͍ͯ͠Δ৔߹ɺ λΠϜΞ΢τΛද͢ྫ֎Λൃੜͤ͞Δɻ )&WରԠ4PDLFUUDQ վ ͷ࣮૷࣍ͷϧʔϓ΁ ϢʔβʔࢦఆͷλΠϜΞ΢τΛ௒աࡁΈ  λΠϜΞ΢τΛද͢ྫ֎Λൃੜͤ͞Δ if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn)

Slide 72

Slide 72 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 ͦΕҎ֎ͷ৔߹͸࣍ͷϧʔϓʹਐΉ 5PCFDPOUJOVFE )&WରԠ4PDLFUUDQ վ ͷ࣮૷࣍ͷϧʔϓ΁ ࣍ͷϧʔϓ΁ if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn)

Slide 73

Slide 73 text

def self.tcp(host, port, ...) loop do end end ໊લղܾͷ։࢝ if ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ then ઀ଓΛ։࢝ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>) if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖ͳ͍ then ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τม਺ͷॳظԽ )&WରԠ4PDLFUUDQ վ ɿ࢒Γͷ՝୊  

Slide 74

Slide 74 text

loop do # ... 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 มߋޙͷ4PDLFUUDQͰ͸ɺϧʔϓͷதͰҰճ͚ͩ *0TFMFDUΛݺͼग़͢ɻ͜ͷ*0TFMFDUͰ଴ػ͢Δ΂͖ ࣌ؒ͸ɺͦͷͱ͖ͷঢ়گʹΑͬͯҟͳΔ ࢒Γͷ՝୊ɿ*0TFMFDUͷ଴ػ࣌ؒ ଴ػ࣌ؒ ϧʔϓͷͨͼʹมΘΔՄೳੑ͕͋Δʜ   ྫ  *1W*1Wͱ΋ʹ໊લղܾத ➡︎ ແظݶ *1W໊લղܾޙɺ*1W໊લղܾΛ଴ػ͢Δ ➡︎ NT ઀ଓΛ։࢝ޙɺ࣍ͷ઀ଓ։࢝·Ͱ଴ػ͢Δ ➡︎ NT

Slide 75

Slide 75 text

loop do # ... 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), ) # ... end *0TFMFDUʹ౉ͨ͢Ίͷద੾ͳ଴ػ࣌ؒΛબ୒͢Δ ϩδοΫΛಋೖ ࢒Γͷ՝୊ɿ*0TFMFDUͷ଴ػ࣌ؒ ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒

Slide 76

Slide 76 text

loop do # ... ends_at = if resolution_store.any_addrinfos? hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, second_to_timeout(current_clock_time, ends_at), ) is_windows_environment ? connecting_sockets.keys : nil, # ... end ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ ղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δ৔߹  ʮղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δʯঢ়گͱ͸ɿ ɾ3FTPMVUJPO%FMBZத ɹ *1Wͷ໊લղܾ͕׬ྃࡁΈɺ͔ͭ઀ଓ։࢝લʹ*1Wͷ໊લղܾΛ଴ػத  ɾ$POOFDUJPO"UUFNQU%FMBZத͋Δ͍͸௒աࡁΈ ɹ ͢ͰʹҰͭҎ্઀ଓΛ։࢝ࡁΈɺ͔ͭղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δ  ɹ  ͷͲͪΒ͔

Slide 77

Slide 77 text

loop do # ... ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, second_to_timeout(current_clock_time, ends_at), ) is_windows_environment ? connecting_sockets.keys : nil, # ... end ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ ղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δ৔߹  3FTPMVUJPO%FMBZதɿ ม਺SFTPMVUJPO@EFMBZ@FYQJSFT@BUʹ ηοτ͞Ε͍ͯΔλΠϜΞ΢τ஋ΛฦΓ஋ͱ͢Δ

Slide 78

Slide 78 text

loop do # ... ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, second_to_timeout(current_clock_time, ends_at), ) is_windows_environment ? connecting_sockets.keys : nil, # ... end ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ ղܾࡁΈͷΞυϨεͷࡏݿ͕͋Δ৔߹  $POOFDUJPO"UUFNQU%FMBZத͋Δ͍͸௒աࡁΈɿ ม਺DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BUʹ ηοτ͞Ε͍ͯΔλΠϜΞ΢τ஋ ͋Δ͍͸OJM ΛฦΓ஋ͱ͢Δ

Slide 79

Slide 79 text

loop do # ... ends_at = if resolution_store.any_addrinfos? resolution_delay_expires_at || connection_attempt_delay_expires_at else hostname_resolved, writable_sockets, except_sockets = IO.select( hostname_resolution_notifier, connecting_sockets.keys, second_to_timeout(current_clock_time, ends_at), ) # ... is_windows_environment ? connecting_sockets.keys : nil, end ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ  ʮղܾࡁΈͷΞυϨεͷࡏݿ͕ͳ͍ʯঢ়گͱ͸ɿ ɾ·ͩ*1W*1Wͱ΋ʹ໊લղܾ͕ऴΘ͍ͬͯͳ͍ঢ়گ ɾશͯͷղܾࡁΈͷΞυϨεѼʹ઀ଓΛ։࢝͠ɺࡏݿ͕ͳ͘ͳͬͨঢ়گ ɹ  ͷͲͪΒ͔ ղܾࡁΈͷΞυϨεͷࡏݿ͕ͳ͍৔߹

Slide 80

Slide 80 text

loop do # ... 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, second_to_timeout(current_clock_time, ends_at), ) # ... is_windows_environment ? connecting_sockets.keys : nil, end ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ ղܾࡁΈͷΞυϨεͷࡏݿ͕ͳ͍৔߹  ͍ͣΕͷ৔߹΋ɺϢʔβʔࢦఆͷλΠϜΞ΢τΛ؅ཧ͢Δม਺ʹ ֨ೲ͞Ε͍ͯΔ஋ͷେ͖͍ํΛฦ͢ ϢʔβʔࢦఆͷλΠϜΞ΢τ͕໌ࣔతʹࢦఆ͞Ε͍ͯͳ͍৔߹ɺ ͜ΕΒͷม਺ʹ͸'MPBU*/'*/*5:͕֨ೲ͞Ε͍ͯΔ ແظݶʹ଴ػ

Slide 81

Slide 81 text

loop do # ... 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), ) # ... end ʮબ୒͞Εͨ଴ػ࣌ؒݱࡏ࣌ࠁʯͷࠩ෼Λ ࣮ࡍͷ଴ػ࣌ؒͱͯ͠*0TFMFDUʹ౉͢ ʮ͍ͭ·Ͱ଴ػ͢Δ͔ʯΛબ୒͢Δ ࣮ࡍͷ଴ػ࣌ؒ FOET@BU͔Βݱࡏ࣌ࠁΛҾ͍ͨࠩ෼  બ୒͞Εͨ଴ػ࣌ؒΛ֨ೲ

Slide 82

Slide 82 text

λΠϜΞ΢τΛ؅ཧ͢Δม਺ΛϦηοτ loop do # ... 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 # ... end *0TFMFDU͔Βฦ͖ͬͯͨ࣌఺ͰλΠϜΞ΢τ͕࣌ؒ աڈ࣌ؒʹͳ͍ͬͯͨ৔߹͸λΠϜΞ΢τͷ؅ཧ͕ ෆཁʹͳΔͷͰͦΕͧΕOJMΛηοτ SFTPMVUJPO@EFMBZ@FYQJSFT@BU͕աڈ࣌ؒ  DPOOFDUJPO@BUUFNQU@EFMBZ@FYQJSFT@BU͕աڈ࣌ؒ 

Slide 83

Slide 83 text

def self.tcp(host, port, ...) loop do end end ໊લղܾͷ։࢝ if ઀ଓ։࢝ͷ৚݅Λຬ͍ͨͯ͠Δ then ઀ଓΛ։࢝ IO.select(<໊લղܾ>, <઀ଓ>, nil, <λΠϜΞ΢τ஋>) if ઀ଓঢ়ଶ͕֬ఆͨ͠ιέοτ͕͋Δ then ઀ଓ֬ೝɹ(੒ޭ͍ͯͨ͠Βreturn) if ໊લղܾ͕׬ྃ then ղܾࡁΈͷIPΞυϨεΛอଘ if ࣍ͷϧʔϓʹೖΔ͜ͱ͕Ͱ͖ͳ͍ then ྫ֎Λൃੜͤ͞Δ λΠϜΞ΢τม਺ͷॳظԽ )&WରԠ4PDLFUUDQ վ ࠓ౓ͦ͜׬੒

Slide 84

Slide 84 text

*NQSPWF4PDLFUUDQ IUUQTHJUIVCDPNSVCZSVCZQVMM 3VCZͷNBTUFSʹϚʔδࡁΈ

Slide 85

Slide 85 text

ΊͰͨ͠ΊͰͨ͠ʜ

Slide 86

Slide 86 text

IUUQTTQFBLFSEFDLDPNDPF@BOBEWFOUVSFPGIBQQZFZFCBMMT TMJEF ঢ়ଶભҠʹدͤ͗͢όʔδϣϯͰ్த·Ͱ࡞ΓࠐΜͰ͍ͨͨΊʜ 5$14PDLFUOFXઈࢍॻ͖௚͠த ⬅︎

Slide 87

Slide 87 text

5PCFDPOUJOVFE

Slide 88

Slide 88 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 4QFDJBMUIBOLTUP !BLS