Slide 1

Slide 1 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ ͝ཡͷεϙϯαʔͷఏڙ ʹΑΓ͓ૹΓ͠·͢

Slide 2

Slide 2 text

slide sponsors Rails !! @mame Kent Beck @hisashim Ember.Sapporo @tricknotes

Slide 3

Slide 3 text

slide sponsors Ruby @iwadon OSS Gate @ktou dRuby Web ( eBook Store) http:// estore.ohmsha.co.jp/titles/978427406609P @hisashim @m_seki "re: " @awazeki Mastodon Pawoo Ruby @pixiv m_seki @tsuboi 07 smalruby @vestige_

Slide 4

Slide 4 text

How to write synchronization mechanisms for Fiber [email protected] RubySapporo.beam#3

Slide 5

Slide 5 text

@m_seki Ruby ERB, dRuby, Rinda ࠷ۙͷcommit: ERBϝϯςφʹk0kubun͞ΜΛadd

Slide 6

Slide 6 text

ΤοηΠ2ຊࡌͤͨʂ ਺ਓ͔Β࣭໰͋Γ·͕ͨ͠ݪߘྉ͸1ຊ෼Ͱ͢

Slide 7

Slide 7 text

2005 - ·ͩॳ࡮Γങ͑·͢ dRuby ʹΑΔ ؔকढ़ஶ ෼ࢄ ɾ Web ϓϩάϥϛϯά 12प೥

Slide 8

Slide 8 text

2012 (-2014 ઈ൛) 2೥Ͱઈ൛

Slide 9

Slide 9 text

2017 re-published on the web CC by SAͳͷͰ࿨༁Ͱ͖ΔΑ?

Slide 10

Slide 10 text

Agenda Fiber Fiber Enumerator Synchronize Multiplexer

Slide 11

Slide 11 text

Fiberͷ͓͞Β͍ Process Thread Fiber ࡾͭͷ࣮ߦओମͷҧ͍͔Βߟ͑Δ

Slide 12

Slide 12 text

Process ↔ Thread ↔ Fiber Process Thread Fiber ͦͷٕज़͸ద੾ͳͷʁ

Slide 13

Slide 13 text

Process ಌΕ͍ͯͨࠒͷ࿩

Slide 14

Slide 14 text

Before Process Key https://www.youtube.com/watch?v=TOnS97C-RGQ

Slide 15

Slide 15 text

Before Process (80s) OS PC BREAKΩʔ΋ϙʔϦϯά

Slide 16

Slide 16 text

ϓϩηε΁ͷಌΕ

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Before Process (90s) Fiber Macintoshͷෆ҆ఆ͞͸ϓϩηε͕͋Ε͹ղܾ͢Δͱ ݴΘΕͯͨ

Slide 19

Slide 19 text

࣮ࡍͷγεςϜ .. ֎෦ͱͷ΍ΓͱΓ͸ආ͚ΒΕͳ͍͠෭࡞༻͸ඞཁ

Slide 20

Slide 20 text

Processes େࣄͳ͜ͱͳͷͰೋ౓ݴ͍·ͨ͠

Slide 21

Slide 21 text

ProcessͰॻ͘ͱ͖ͷؾ࣋ͪ

Slide 22

Slide 22 text

ProcessͰॻ͘ͱ͖ͷؾ࣋ͪ Skip!

Slide 23

Slide 23 text

IPC͸ΊΜͲ͍͘͞ pipe SystemV IPC socket ͦΕͧΕಛ௃͕͋Γɺ࢖ͬͯΈͯΘ͔ΔΊΜͲ͘ ͕͋͞͞Δ

Slide 24

Slide 24 text

Thread 1ϓϩηεͰίΞΛ࢖͍੾Βͳͯ͘΋͍͍͡ΌΜ

Slide 25

Slide 25 text

ThreadͰॻ͘ͱ͖ͷؾ࣋ͪ ݟ͑Δ͚Ͳ৮Βͳ͍Ϟϥϧ

Slide 26

Slide 26 text

Threadʹඞཁͳၗຫ͞ OS OS

Slide 27

Slide 27 text

Fiber Thread Thread Thread mrubyʹ͸Threadͳ͍͔ΒFiberҰ୒

Slide 28

Slide 28 text

Fiberʹඞཁͳࣗ৴ Ruby

Slide 29

Slide 29 text

FiberͰॻ͘ͱ͖ͷؾ࣋ͪ ... Fiber ఆੴΛݟ͚ͭΔ·Ͱ͕͍ͨ΁Μ

Slide 30

Slide 30 text

Process ↔ Thread ↔ Fiber Process Thread Fiber

Slide 31

Slide 31 text

Process ↔ Thread ↔ Fiber Fiber Thread Process ͋ͳͨ͸ͳʹΛ࢖͏΂͖ʁ

Slide 32

Slide 32 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ ෼͘Β͍͔ͳ ✓ 1SPDFTT 5ISFBE 'JCFS ✓ ࣍͸'JCFSΛקΊΔΑʂ

Slide 33

Slide 33 text

ͳͥFiberͷ࿩Λ͢Δͷ͔ Fiber EventMachine͍ͬͯ͢͝@tricknotesʹڭΘͬͨΑ͏ͳ...

Slide 34

Slide 34 text

ͳͥFiberͷ࿩Λ͢Δͷ͔ X11 GUI socket 1 Fiber͕͋Δͱॻ͖΍͘͢ͳΔ΋ͷΛΑ͘ॻ͍ͯͨ

Slide 35

Slide 35 text

ͳͥFiberͷ࿩Λ͢Δͷ͔ Thread

Slide 36

Slide 36 text

Fiberೖ໳ Fibonacci Enumerator Rdv SizedQueue, channel Multiplexer 3ͭͷςʔϚͰઆ໌͠·͢

Slide 37

Slide 37 text

࠷ॳͷςʔϚ Enumerator Fiber API Fiber Enumertor

Slide 38

Slide 38 text

Α͋͘ΔFibonacci [0, 1] [1, 1] [2, 2] [3, 3] [4, 5] [5, 8] [6, 13] [7, 21] [8, 34] [9, 55] ్தͷ஋Λฦ͢ͷ͕೉͍͠ def fibonacci(n) a, b = 1, 1 n.times do |i| p [i, a] a, b = b, a + b end end fibonacci(10)

Slide 39

Slide 39 text

FiberͰॻ͖௚͢ API fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end def fibonacci(n) a, b = 1, 1 n.times do |i| p [i, a] a, b = b, a + b end end fibonacci(10) FiberΛ࢖͏ͱ్தܦաͷ஋ΛฦͤΔ

Slide 40

Slide 40 text

API Fiber.new Fiber#resume Fiber.yield

Slide 41

Slide 41 text

Fiber.new Fiber fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end Fiber࡞͚ͬͨͩ

Slide 42

Slide 42 text

Fiber#resume Fiber fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end FiberʹͳΓ͖ͬͯಈ͘

Slide 43

Slide 43 text

Fiber.yield resume Fiber resume fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end resumeʹ໭Δ

Slide 44

Slide 44 text

resume, again resume yield fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end

Slide 45

Slide 45 text

resumeͷߦ͖ઌ Fiber new resume Fiber Fiber.yield resume ...

Slide 46

Slide 46 text

APIΛઆ໌ͨ͠ resume yield

Slide 47

Slide 47 text

EnumeratorͰॻ͖௚͢ fib = Fiber.new do a, b = 1, 1 while true Fiber.yield(a) a, b = b, a + b end end 10.times do |n| p [n, fib.resume] end def fibonacci a, b = 1, 1 while true yield(a) a, b = b, a + b end end fib = to_enum(:fibonacci) 10.times do |n| p [n, fib.next] end

Slide 48

Slide 48 text

Enumerator ❌ Fiber

Slide 49

Slide 49 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ &OVNFSBUPSͰ"1*Λઆ໌ ✓ ೉ָ͕͠͞͠Ίͳ͍ ✓ ࣍͸3EW

Slide 50

Slide 50 text

࣍ͷςʔϚ

Slide 51

Slide 51 text

QueueΛհͨ͠ڠௐ Queue Thread Thread q = SizedQueue.new(1) Thread.new do 10.times do |n| sleep(rand) q.push(n) p [:push, n] end end Thread.new do 10.times do |n| sleep(rand) p [:pop, q.pop] end end.join

Slide 52

Slide 52 text

͜ΕͷFiber൛ Rdv Fiber rendez-vous rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume

Slide 53

Slide 53 text

rendez-vous ⚓ rendez-vous

Slide 54

Slide 54 text

ड͚औΔଆ͕଴ͭ৔߹ ⚓ rendez-vous

Slide 55

Slide 55 text

͜͏͍͏৔߹΋͋Δ ⚓ rendez-vous ΋ͪΖΜٯ΋͋Δ

Slide 56

Slide 56 text

Rdvͷ࣮૷ initialize push pop def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end

Slide 57

Slide 57 text

࠷ۙ޷͖ͳΠσΟΦϜ resume yield

Slide 58

Slide 58 text

ͱΓ͋͑ͣresume Fiber.new resume Thread.new resume

Slide 59

Slide 59 text

initialize @reader pop @writer push Fiber def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end

Slide 60

Slide 60 text

push @reader (yield) @reader (resume) def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end

Slide 61

Slide 61 text

@reader͕͍ͳ͍ Fiber.current yield def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end

Slide 62

Slide 62 text

@reader͕͍Δ @reader resume pop Fiber def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end

Slide 63

Slide 63 text

pop @writer (yield) @writer (resume) def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end pushͱҰॹͩΑʂ Skip!

Slide 64

Slide 64 text

@writer͕͍ͳ͍ Fiber.current yield def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end Skip!

Slide 65

Slide 65 text

@writer͕͍Δ @writer resume push Fiber def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end Skip!

Slide 66

Slide 66 text

ݕࠪதͷഉଞ੍ޚ Fiber Thread def initialize @reader = [] @writer = [] end def push(it) if @reader.empty? @writer << [it, Fiber.current] return Fiber.yield end @reader.shift.resume(it) end def pop if @writer.empty? @reader << Fiber.current return Fiber.yield end value, fiber = @writer.shift fiber.resume return value end Thread೴ͷਓ͸υΩυΩͯ͠Δͱࢥ͏

Slide 67

Slide 67 text

Threadͱͷҧ͍ Thread Monitor

Slide 68

Slide 68 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume Fiber.newした
 kara-matzを召喚

Slide 69

Slide 69 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume kara-matzをresume
 kara-matzのターン


Slide 70

Slide 70 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume kara-matzのpush!
 相手がいない。
 自分とデータをメモしyield。ターン終了

Slide 71

Slide 71 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume メインのターン
 Fiber.new
 ichi-matzを召喚

Slide 72

Slide 72 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume ichi-matzをresume
 ichi-matzのターン


Slide 73

Slide 73 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume ichi-matzのpop!
 ichi-matzはメモを読んだ
 データを手にいれた。kara-matzをresumeしターン終了

Slide 74

Slide 74 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume kara-matzのpush!
 相手がいない。
 自分とデータをメモしyield。ターン終了

Slide 75

Slide 75 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume ichi-matzのpop!
 ichi-matzはメモを読んだ
 データを手にいれた。kara-matzをresumeしターン終了 Skip!

Slide 76

Slide 76 text

10 Skip!

Slide 77

Slide 77 text

͏༷͘͝ࢠ rdv = Rdv.new Fiber.new do 10.times do |n| rdv.push(n) p [:push, n] end end.resume Fiber.new do 10.times do |n| p [:pop, rdv.pop] end end.resume ichi-matzはしんでしまった
 メインのターン
 メインはしんでしまった Skip!

Slide 78

Slide 78 text

͏͖ͦ͝͏ʂ ͕͢͞

Slide 79

Slide 79 text

͜͜ͷ·ͱΊ Fiber resume yield

Slide 80

Slide 80 text

͜͜ͷ·ͱΊ Thread Thread Fiber ޿ౡͰ͸@_ko1͔ΒAutoFiberͱ͍͏ఏҊΛ঺հͯ͠ ͍ͨɻϒϩοΫͦ͠͏ʹͳͬͨΒࣗಈతʹίϯς Ωετ੾Γସ͑͢ΔFiberɻ͜͜͸ͦΕ΁ͷճ౴

Slide 81

Slide 81 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ 'JCFSͷಉظͷ࣮૷ ✓ 3EW ✓ ࣍͸ιέοτϓϩάϥϛ ϯά

Slide 82

Slide 82 text

࣍ͷςʔϚ socket

Slide 83

Slide 83 text

͢͢Ί͔ͨ dRuby Thread Thread Fiber

Slide 84

Slide 84 text

ૉ๿͚ͩͲҰ్ I/O 1 def main_loop loop do select fds.each do |fd| call_callback end end end def on_accept c = accept loop do read_request(c) do_it write_response(c) end end def read_n(fd, sz) ... ... end

Slide 85

Slide 85 text

Thread൛ fd Thread def main_loop loop do select fds.each do |fd| call_callback end end end def on_accept c = accept Thread.new(c) do |fd| loop do read_request(fd) do_it write_response(fd) end end end def read_n(fd, sz) ... ... end ௥Ճ͸͚ͩ͜͜ ௥Ճ͸͚ͩ͜͜

Slide 86

Slide 86 text

Fiber൛ def main_loop loop do select fds.each do |fd| call_callback end end end def on_accept c = accept Fiber.new do loop do read_request(c) do_it write_response(c) end end.resume end def read_n(fd, sz) ... ... end Swapped with Fiber

Slide 87

Slide 87 text

Fiber൛վ I/O I/O def main_loop loop do select fds.each do |fd| call_callback end end end def on_accept c = accept Fiber.new do loop do read_request(c) do_it write_response(c) end end.resume end def read_n(fd, sz) ... fd.read_nonblock(sz) rescue WaitReadable Fiber.yield retry end

Slide 88

Slide 88 text

Block-ish non-block I/O Fiber.yield main_loop resume def main_loop loop do select fds.each do |fd| call_callback end end end def on_accept c = accept Fiber.new do loop do read_request(c) do_it write_response(c) end end.resume end def read_n(fd, sz) ... fd.read_nonblock(sz) rescue WaitReadable Fiber.yield retry end

Slide 89

Slide 89 text

ίʔϧόοΫͰresume

Slide 90

Slide 90 text

Bartender fd readable, writable https://github.com/seki/bartender

Slide 91

Slide 91 text

Bartender::Context readable, writable block-ish non-block I/O Context#[]=(event, fd, callback) Πϕϯτछʢ:read, :writeʣͱfdͷ૊ʹίʔϧόοΫΛొ࿥

Slide 92

Slide 92 text

_read() read_nonblock readable retry Fiber def _read(fd, sz) return fd.read_nonblock(sz) rescue IO::WaitReadable wait_readable(fd) retry end def wait_readable(fd); wait_io(:read, fd); end def wait_io(event, fd) self[event, fd] = Fiber.current.method(:resume) Fiber.yield ensure delete(event, fd) end

Slide 93

Slide 93 text

read_nonblock sz IO::WaitReadable def _read(fd, sz) return fd.read_nonblock(sz) rescue IO::WaitReadable wait_readable(fd) retry end def wait_readable(fd); wait_io(:read, fd); end def wait_io(event, fd) self[event, fd] = Fiber.current.method(:resume) Fiber.yield ensure delete(event, fd) end

Slide 94

Slide 94 text

wait_io() resume Fiber.yield select resume readable def _read(fd, sz) return fd.read_nonblock(sz) rescue IO::WaitReadable wait_readable(fd) retry end def wait_readable(fd); wait_io(:read, fd); end def wait_io(event, fd) self[event, fd] = Fiber.current.method(:resume) Fiber.yield ensure delete(event, fd) end

Slide 95

Slide 95 text

I'll show this to you on an actual application

Slide 96

Slide 96 text

tiny_drbͷൈਮ read def req_drb(reader) ref = load(reader, false) msg = load(reader) argc = load(reader) argv = argc.times.collect {load(reader)} block = load(reader, false) [ref, msg, argv] end def load(reader, marshal=true) sz = reader.read(4) sz = sz.unpack('N')[0] data = reader.read(sz) return data unless marshal begin Marshal.load(data) rescue DRb::DRbUnknown.new($!, data) end end

Slide 97

Slide 97 text

צҧ͍ ❌ readable ❌ writable

Slide 98

Slide 98 text

ੲΑ͘ݟͨόά select()

Slide 99

Slide 99 text

σϞʢ͸͋Γ·ͤΜʣ sample ... ...

Slide 100

Slide 100 text

tiny_drb.rb irb -r drb irb -r drb tiny_drb.rb Rdv https://github.com/seki/bartender/tree/master/sample Skip!

Slide 101

Slide 101 text

tiny_drbͷ͓΋͠Ζ͍ͱ͜Ζ block-ish nonblock I/O Fiber select Rdv

Slide 102

Slide 102 text

ଞʹࢼ࡞ͨ͠΋ͷ Fiber Rinda::TupleSpace Fiber WEBrick FD Thread Skip!

Slide 103

Slide 103 text

Threadͱͷ଴ͪ߹Θͤ Thread.value IO.pipe close class ThreadTask def initialize(*args, &block) left, @right = IO.pipe @task = Thread.new do begin block.call(*args) ensure left.close end end end def value if @right Bartender.wait_readable(@right) @right.close end @task.value ensure @right = nil end end Skip!

Slide 104

Slide 104 text

Multiplexerͷ·ͱΊ vs Thread Fiber block-ish non-block I/O

Slide 105

Slide 105 text

Fiberೖ໳ͷ·ͱΊ Fibonacci Enumerator Rdv SizedQueue, channel Multiplexer

Slide 106

Slide 106 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ ࣌ؒ͋Δ͔ͳʁ ✓ ͓·͚

Slide 107

Slide 107 text

͓·͚ Fiber ... Skip?

Slide 108

Slide 108 text

ࠓճͷྫ͸

Slide 109

Slide 109 text

᠘ Fiber Thread FiberError gem

Slide 110

Slide 110 text

ͭ·Γ Fiber ࢖༻͢Δgemͷ࢓૊Έ͘Β͍Θ͔ͬͯͳ͍ͱ

Slide 111

Slide 111 text

ϋϚΔྫ Fiber Twitter JSON.parse String JSON.parse

Slide 112

Slide 112 text

ϋϚΓͦ͏ͳྫ RDBMS ...

Slide 113

Slide 113 text

͠͹Β͓͘଴͍ͪͩ͘͞ ✓ ͓ΘΓ

Slide 114

Slide 114 text

·ͱΊ Thread Fiber Fiber API I/O

Slide 115

Slide 115 text

Process ↔ Thread ↔ Fiber Fiber Thread Process ͋ͳͨ͸ͳʹΛ࢖͏΂͖ʁ

Slide 116

Slide 116 text

ϓϩάϥϛϯάErlangΑΓ -module(kvs). -export([start/0, store/2, lookup/1]). start() -> register(kvs, spawn(fun() -> loop() end)). store(Key, Value) -> rpc({store, Key, Value}). lookup(Key) -> rpc({lookup, Key}). rpc(Q) -> kvs ! {self(), Q}, receive {kvs, Reply} -> Reply end. loop() -> receive {From, {store, Key, Value}} -> put(Key, {ok, Value}), From ! {kvs, true}, loop(); {From, {lookup, Key}} -> From ! {kvs, get(Key)}, loop() end.

Slide 117

Slide 117 text

serverͷϝΠϯϧʔϓ -module(kvs). -export([start/0, store/2, lookup/1]). start() -> register(kvs, spawn(fun() -> loop() end)). store(Key, Value) -> rpc({store, Key, Value}). lookup(Key) -> rpc({lookup, Key}). rpc(Q) -> kvs ! {self(), Q}, receive {kvs, Reply} -> Reply end. loop() -> receive {From, {store, Key, Value}} -> put(Key, {ok, Value}), From ! {kvs, true}, loop(); {From, {lookup, Key}} -> From ! {kvs, get(Key)}, loop() end. server main loop

Slide 118

Slide 118 text

client͸ࡶʹϒϩοΫ x -module(kvs). -export([start/0, store/2, lookup/1]). start() -> register(kvs, spawn(fun() -> loop() end)). store(Key, Value) -> rpc({store, Key, Value}). lookup(Key) -> rpc({lookup, Key}). rpc(Q) -> kvs ! {self(), Q}, receive {kvs, Reply} -> Reply end. loop() -> receive {From, {store, Key, Value}} -> put(Key, {ok, Value}), From ! {kvs, true}, loop(); {From, {lookup, Key}} -> From ! {kvs, get(Key)}, loop() end. client API

Slide 119

Slide 119 text

΋͜͠Εਅࣅͯ͠Δͱ x -module(kvs). -export([start/0, store/2, lookup/1]). start() -> register(kvs, spawn(fun() -> loop() end)). store(Key, Value) -> rpc({store, Key, Value}). lookup(Key) -> rpc({lookup, Key}). rpc(Q) -> kvs ! {self(), Q}, receive {kvs, Reply} -> Reply end. loop() -> receive {From, {store, Key, Value}} -> put(Key, {ok, Value}), From ! {kvs, true}, loop(); {From, {lookup, Key}} -> From ! {kvs, get(Key)}, loop() end. serverͷओॲཧͰrpcΛ ݺΜͩΒݻ·Δ͔΋...

Slide 120

Slide 120 text

2छྨͷϝοηʔδΛѻ͏ 1. Receive 4. Do it 2. Send task1 3. Receive task1 5. Send receive 2種類のメッセージ

Slide 121

Slide 121 text

͋ͱͰ΍ΔϦετ 1. Receive 4. Do it 2. Send task1 3. Receive task1 5. Send 処理できないやつをあとでやる

Slide 122

Slide 122 text

͋ͱͰ΍Δ࡞ઓ... ࣗ෼ͷ౎߹ͷྑ͍࣌ʹ΍ΔΑ ΍Γ͔͚ͷ͕ऴΘ͔ͬͯΒ࣍ͷཁٻΛ΍Δ ࣗ෼͸͏·͘ߦ͘

Slide 123

Slide 123 text

૬ޓʹґଘ͢Δ෦෼͕͋ͬͨΒ... ݏͳ༧ײ͕͢Δ

Slide 124

Slide 124 text

"͋ͱͰ΍Δ"Λ࣋ͬͨ··͓ޓ͍ʹreplyΛ଴ͬͪΌ͏ ݏͳ༧ײ͕͢Δ

Slide 125

Slide 125 text

20ੈل ػೳ෼ࢄ ͜ͷόά΍ͬͨ͜ͱ͋Δ

Slide 126

Slide 126 text

Ӆ͞Εͨґଘ͕͋ͬͨ ࣌ʑɺΈΜͳ͕reply଴ͪʹͳΔ ୭΋ࢭ·ͬͯͳ͍͚ͲγεςϜ͸ࢭ·ͬͯΔ