Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Actor, Thread and me (RubyKaigi2015)

Actor, Thread and me (RubyKaigi2015)

Everybody says. Actor helps to solve the multithreading problem. Actor is awesome. Threads are 💩

Really?

An actor model is "just a model", just like MVC.

Today, Recap what Actor Model is.

seki at druby.org

December 13, 2015
Tweet

More Decks by seki at druby.org

Other Decks in Programming

Transcript

  1. slide sponsors
    嫣鹈،ؙة٦ךֿהח鑫׃ֻז׸׷ؔٝٓ؎ٝ⿫⸇דֹ׷؝ىُصذ؍׌״

    TBQQPSPCFBNHJUIVCJP
    ؟ٝٓ؎ؤ⳿ꨡד遤ֻ3VCZ8PSME$POGFSFODFծ嫣䎃㥨鐰㹋倵⚥דׅկ勻䎃
    ׮װ׶תׅךדծֶ㉏ְさ׻ׇ♴ְׁZBODZB
    虠加歕ջ梾楤㼔Ꟍ枾䒍莔ռ׀勻䏄ֶ䖉׍׃גֶ׶תׅ!PHJKVO
    սט׷⹫վ䎃剢ַ׵ך➬✲!1613-
    ջأذ؍٦ـؤռ䋆涪㡰⚥!NB
    ջأذ؍٦ـؤռ顠ְת׃׋!WFTUJHF@
    ջأذ؍٦ـؤռ顠ְתׅ!USBDL
    ֿ׿ח׍כֿ׿ח׍כ!IJCBSJZB

    View full-size slide

  2. more slide sponsors
    ׻׋׃׋׍ծה׷ן٦ׅה!USJDLOPUFT
    הגַכ剢דׅկ✮㹀ծ甧גגְֶג♴ְׁי!NBNF
    5BLBZVLJ,BNJZBNB!UBLLJJ
    ת׌ֹ׭זְַ׵ծ罋ִתׅ![[BL@KQ
    E3VCZח״׷ⴓ侔٥8FCفؚٗٓىؚٝ ؔ٦ي爡F#PPL4UPSF
    IUUQ
    FTUPSFPINTIBDPKQUJUMFT1!IJTBTIJN
    ׉׸ד׮EFGBVMU@TDPQF⢪ְתַׅ!TVHJOPZ
    ؔٔآشٕ5ءٍخך5.*9ծ倜㉀ㅷؙٓحثغحؚ׮㥨鐰涪㡰⚥!JHBJHB
    ׫זׁתծTFLJ眍׾ֶ嚂׃׫ֻ׌ְׁկ䊛䃵歲꥔ך倯כծLBXBTBLJSCծZPLPIBNBSC׾
    ֶ鑐׃ֻ׌ְׁկ,ذٖؽך飑ⰅכծTFLJׁ׿穗歋ד׀湱锑ְ׋׌ֽ׷ה׀⼿⸂׃תׅկ!UTVCPJ

    View full-size slide

  3. T-shirts sponsors
    TV[VSJKQN@TFLJ

    View full-size slide

  4. sticker sponsors

    View full-size slide

  5. Pragmatic Bookshelf Author

    View full-size slide

  6. ΋͏ઈ൛
    out of print

    View full-size slide

  7. ॳ࡮Γ10प೥
    dRuby
    ʹΑΔ
    ؔকढ़ஶ
    ෼ࢄ
    ɾ
    Web
    ϓϩάϥϛϯά
    10th anniversary after the 1st edition

    View full-size slide

  8. Agenda
    ΞΫλʔϞσϧ
    ࣮૷
    - Actor Model
    - Implementation

    View full-size slide

  9. Actor is better than Thread
    ϚϧνεϨουͰൃੜ͢Δ໰୊͕ղܾ͢Δ
    εϨουͰਖ਼͘͠ॻ͘ͷ͸Ή͔͍ͣ͠
    ΞΫλʔͳΒ؆୯ʹॻ͚Δ
    εϨου͸
    ຊ౰ʁ
    Everybody says. Actor helps to solve the multithreading problem.
    Actor is awesome. Threads are .
    Really?

    View full-size slide

  10. Actor and Thread
    εϨουؒͷσʔλͷަ׵Λ੍ݶ
    ෳ਺ͷεϨου͕σʔλΛॻ͖׵͑ͳ͍
    ΞΫλʔͳΒ؆୯ͩ
    ͑ʁͦ͜ͳͷʁ
    - Control passing data between threads
    - Properly handle changeing data between threads
    - So, that's the point?

    View full-size slide

  11. Process and Thread
    εϨουͱϓϩηεͷҧ͍
    ϝϞϦۭؒΛڞ༗Ͱ͖Δ
    ϝϦοτͰ͋ΓσϝϦοτͰ͋Δ
    ͭ·ΓͦΕ͕ͦ͜ಛ௃Ͱ͋Δ
    ϓϩηεͰ͍͍ͷͰ͸ʂ
    Difference between Thread / Process
    - Could share memory space
    - So, that's one of the big characteristics of threads
    Well, couldn't it be process ...!!

    View full-size slide

  12. Actor Model, Again
    ΞΫλʔϞσϧΛ͓͞Β͍͍ͨ͠
    Recap what Actor Model is

    View full-size slide

  13. Model
    ΞΫλʔϞσϧ͸ͨͩͷϞσϧ
    MVCΈ͍ͨʹͨͩͷϞσϧ
    ໛ܕ
    ΑΓྑ͍εϨουͰ͸ͳ͍ͱࢥ͏
    An actor model is "just a model;"
    - Just like MVC
    An actor model probably isn't a "better thread"

    View full-size slide

  14. Actor Model
    Actor
    Message
    Ether

    View full-size slide

  15. Message
    ѼઌΛࢦఆ͢Δ
    Specify the destination

    View full-size slide

  16. Actor
    ࣮ߦओମ
    ୭ʹ΋अຐ͞Εͳ͍
    ࣗ෼ͷϖʔεͰ࢓ࣄ͢Δ
    - Execution subject
    - Cannot be interrupted by anyone
    - Work at your own pace

    View full-size slide

  17. Messaging System
    ActorͱActorͷؒͰ

    ϝοηʔδΛ఻೻͢Δ
    Passing message between Actors

    View full-size slide

  18. Ether (Æther)
    ͔ͭͯޫͷ೾Λ఻͑Δഔ࣭ͱͯ͠Ծ૝͞Ε͍ͯͨ෺࣭
    Ethernetͷޠݯ?
    ͔͍͍͔ͬ͜Βࠓ೔͸Τʔςϧ
    - Æther used to be thought as medium that transmit llight waves
    - Originated from Ethernet ?
    - "Æther" sounds good to me, so I'll call Messaging System "Ether" today

    View full-size slide

  19. Send
    ࣗ෼ͷ౎߹ͷྑ͍࣌ʹ

    ϝοηʔδΛૹΔ͜ͱ͕Ͱ͖Δ
    ฦ৴͕ඞཁͳΒͦΕ΋

    ϝοηʔδͰ΋Β͏
    Could send messages whenever you wish
    If necessary, you could also receive message for a reply

    View full-size slide

  20. Receive
    ࣗ෼ͷ౎߹ͷྑ͍࣌ʹࣗ෼Ѽͷ

    ϝοηʔδΛड͚औΔ
    ॱෆಉ
    Could receive messages whenever you wish.
    Received in random order

    View full-size slide

  21. ͜Ε͚ͩͷಓ۩ͰγεςϜΛ
    ॻ͜͏
    ଞʹActorͷੜ੒΋͋Δ͚ͲׂѪ
    ےτϨΈ͍ͨͳײ͡
    ࢥߟ࣮ݧʁ
    Let's try to make system with these instruments
    - Skip other topics like Actor Creation
    - Maybe a thought experiment?

    View full-size slide

  22. ਎ۙʹ͋ΔΞΫλʔϞσϧ
    Win32ΞϓϦͳͲͷEvent Drivenͳ΍ͭ
    Ͱ΋εϨου͕ඞཁʹͳͬͨΜͩΑͳ
    ϞϊεϨουͰselectଐΛ࢖ͬͨsocketϓϩ
    άϥϛϯάͱ͔
    N̋de.js͸ʁ
    ͍ΖΜͳγεςϜͰ΋ݟΒΕΔ
    Common examples of Actor Model
    - MFC,
    - Single threaded socket client/server programming using select
    - Like these, you can see it in other systems

    View full-size slide

  23. Simple Worker
    1. Receive
    2. Working
    3. Send

    View full-size slide

  24. client / server
    1. Receive
    2. Working
    3. Send
    0. Send
    4. Receive

    View full-size slide

  25. Simple Worker
    def oso_matz_RPC
    request = ...
    ether.send(:oso_matz, request)
    return ether.receive
    end
    while true
    request = ether.receive
    result = do_it(request)
    ether.send(request.from, result)
    end

    View full-size slide

  26. ࣗ෼ͷ౎߹͚ͩͰಈ͘
    ୭ʹ΋ׯব͞Εͳ͍
    ౎߹ͷྑ͍࣌ʹಡΈɺ౎߹ͷྑ͍࣌ʹॻ͘
    ؆୯ʂ҆৺ʂ
    εϨουͳΜͯ
    ຊ౰͔ʁ
    Works at your convenience
    - No one interrupts you, Read and write whenever you wish
    - Reliable and easy to use
    Is this true ?

    View full-size slide

  27. Worker͕ڠௐ͢Δέʔε
    ୭͔ͷ݁ՌΛ࢖ͬͯ͞Βʹܭࢉ͢Δέʔε
    Collaborative workers
    When you work with the results of your collaborator's calculation

    View full-size slide

  28. ୭͔ͷ݁ՌͰܭࢉ
    while true
    request = ether.receive
    # jushi_matz RPC
    ether.send(:choro_matz, task1)
    task1_value = ether.receive
    result = do_it(request, task1_value)
    ether.send(request.from, result)
    end
    SFDFJWF✳א
    2種類のメッセージ
    When you work with the results

    View full-size slide

  29. 2छྨͷϝοηʔδΛѻ͏
    1. Receive
    4. Do it
    2. Send task1
    3. Receive task1
    5. Send
    SFDFJWF✳א
    2種類のメッセージ
    2 types of messages

    View full-size slide

  30. ͋ͱͰ΍Δ
    pending = []
    while true
    request = pending.shift || ether.receive
    ether.send(:choro_matz, task1)
    while true
    message = ether.receive
    if message.reply?
    task1_value = message
    break
    end
    pending << message
    end
    result = do_it(request, task1_value)
    ether.send(request.from, result)
    end
    欲しいものを待つ
    あとでやるリスト
    Do it Later
    - wait for reply message
    - with list of Do it Later
    あとでやるリスト

    View full-size slide

  31. ͋ͱͰ΍ΔϦετ
    1. Receive
    4. Do it
    2. Send task1
    3. Receive task1
    5. Send
    処理できないやつをあとでやる
    Stock and process do-it-later strategy

    View full-size slide

  32. ͋ͱͰ΍Δ࡞ઓ...
    ࣗ෼ͷ౎߹ͷྑ͍࣌ʹ΍ΔΑ
    ΍Γ͔͚ͷ͕ऴΘ͔ͬͯΒ࣍ͷཁٻΛ΍Δ
    ࣗ෼͸͏·͘ߦ͘
    - Process whenever you're ready
    - Finish working process before moving on to the next request
    - For myself, it works fine

    View full-size slide

  33. ૬ޓʹґଘ͢Δ෦෼͕͋ͬͨΒ...
    ݏͳ༧ײ͕͢Δ
    Bad smells...
    - What if there were mutual dependency between workers..

    View full-size slide

  34. "͋ͱͰ΍Δ"Λ࣋ͬͨ··͓ޓ͍ʹreplyΛ଴ͬͪΌ͏
    ݏͳ༧ײ͕͢Δ
    They wait for their next reply, even though the have their stocks at hand

    View full-size slide

  35. 20ੈل
    ػೳ෼ࢄ
    ͜ͷόά΍ͬͨ͜ͱ͋Δ
    These bugs sound familiar
    - 20th century
    - Functional distribution

    View full-size slide

  36. Ӆ͞Εͨґଘ͕͋ͬͨ
    ࣌ʑɺΈΜͳ͕reply଴ͪʹͳΔ
    ୭΋ࢭ·ͬͯͳ͍͚ͲγεςϜ͸ࢭ·ͬͯΔ
    Hidden dependency...revealed
    - All of the workers wait for their replies once in a while
    - Everyone is trying to work, but the system itself stops

    View full-size slide

  37. ·͞ʹnon-blocking
    ฦ৴ʹݶΒͣෳ਺ͷϝοηʔδΛ଴ͭέʔε
    Future/PromiseͰͷ݁Ռ໰͍߹Θͤͱ͔
    ෳ਺ͷΠϕϯτΛ଴ͬͯॲཧ͢Δͱ͔
    (ڞ༗ࢿݯͱ͔΋)
    This WAS actually "non-blocking"
    When multiple messages, including replies, are held by workers
    - e.g. Query for the results between Future and Promise
    - e.g. Start processing when some events finish
    - Not only messages but the other shared resources

    View full-size slide

  38. ڞ༗ࢿݯ΁ͷૢ࡞͸ڠௐ͢Δඞཁ͕͋Δ
    ΞΫλʔͱߟ͑ͯ෼ੳ͢Δͱ͍͍Αʂ
    খωλ/ڞ༗ࢿݯͷૢ࡞
    e.g. How to use shared resources between Actors?
    I think shared is an actor.

    View full-size slide

  39. ͋ͱͰ΍Δ࡞ઓ...
    μϝͩͬͨ
    ࣗ෼ͷ౎߹ͷྑ͍࣌ʹಡΈɺॲཧ͠ɺॻ͘
    ΈΜͳ͕ͦ͏Ͱ͖Δʹ͸Ͳ͏͢Δ͔ʁ
    Do-it -later strategy. It doesn't work.
    How do you make it so that everybody can read, process, and write at
    their own pace?

    View full-size slide

  40. ͦ͏͍͏ঢ়گ͕ѱ͍
    શͯͷΞΫλʔ͕୭ʹ΋ґଘ͠ͳ͍΂͖ʁ
    ΋͔ͯ͠͠αϒϧʔνϯͰ͍͍ʁ
    ͦΕͳΒΞΫλʔͷҙٛ͸...
    The issue is this situation
    - Every actor should only depend on themselves
    -- Does subroutine work for this?
    --- if then, what's the meaning of Actor?

    View full-size slide

  41. ͦ͏͍͏ঢ়گ͕ѱ͍
    ਖ਼͘͠ॻ͚͹͏·͍͘͘ͷʹʂ
    ͍͍ͨͯͦ͏ ʂ
    - write it the right way, and it will work fine!
    -- This applies to usually everything

    View full-size slide

  42. ͦ͏͍͏ঢ়گ͕ѱ͍
    ݁Ռʹڵຯ͕ͳ͍ϒϩʔυΩϟετܥ޲͖ʁ
    It may work if you only do broadcasting.

    View full-size slide

  43. ͦ͏͍͏ঢ়گΛड͚ೖΕΔ
    ΞΫλʔ͸Ϟσϧ / ےτϨ / ࢥߟ࣮ݧ
    Ή͠Ζঢ়گΛड͚ೖΕΑ͏ʂ
    Accept these situations
    - Actor is a model and a thought experiment
    -- Accept these difficult situations

    View full-size slide

  44. ͜͏ͨ͠ΒͲ͏ͩΖ͏
    ࣗ෼͸ΈΜͳͷ౎߹ʹ߹ΘͤΔɺͱఘΊΔ
    ࢓ࣄͷ్தͰ΋Ͱ͖Δ͚͖ͩͭ͋͏
    My suggestions:
    - Each actor waits and serves others first, even if you have any process left

    View full-size slide

  45. event driven
    while true
    event = ether.receive
    case event.kind
    when :request
    do_request(event)
    when :reply_choro_matz
    do_reply_choro_matz(event)
    ....
    end
    end

    View full-size slide

  46. ͋͋callbackͶ
    while true
    event = ether.receive
    case event.kind
    when :request
    do_request(event)
    when :reply_choro_matz
    do_reply_choro_matz(event)
    ....
    end
    end
    callback はこの分岐が
    動的になっただけ
    Ah, callbacks
    - This branch just turned dynamic for callback

    View full-size slide

  47. ్தܦաΛϝϞ͢ΔҨݴ࡞ઓ
    def do_request(event)
    uid = push_context { :from => event.form }
    ether.send(:choro_matz, [args, uid])
    end
    def do_reply_choro_matz(reply)
    uid = reply.uid
    context = pop_context(uid)
    value = do_oso_matz(context, reply)
    ether.send(context[:from], value)
    end
    save context
    restore context
    Save-the-progress strategy

    View full-size slide

  48. ॲཧͷྲྀΕΛࣗવʹॻ͚ͳ͍
    ίϯςΩετΛཅʹѻΘͳ͖ΌͳΒͳ͍
    ॲཧΛࣗવͳྲྀΕͱͯ͠ॻ͖ʹ͍͘
    while true
    request = ether.receive
    # jushi_matz RPC
    ether.send(:choro_matz, task1)
    task1_value = ether.receive
    result = do_it(request, task1_value)
    ether.send(request.from, result)
    end
    元は単純だったのに
    Difficult to write the process naturally
    - It was simple originally... (but become complex)

    View full-size slide

  49. ෳ਺ͷίϯςΩετ͕͋ͬͨ
    ࣗ෼͚͕ͩσʔλΛૢ࡞͢Δͷ͕҆શͷࠜڌ
    ͍·͸ෳ਺ͷίϯςΩετ͕ڞ༗͢Δ
    There were contexts
    - Specifying who handles data is important for safety
    - But now they are handled in some contexts

    View full-size slide

  50. Fiberͷ࢖͍ํʹࣅͯΔʁ
    ϞϊεϨουͰෳ਺ͷίϯςΩετ
    ໌ࣔతͳίϯςΩετ੾Γସ͑
    ಉ͡ऑ఺͕͋Δ
    Similar to Fiber?
    - Some contexts in a single thread
    - Explicit context switch
    - Same weak point here

    View full-size slide

  51. ࢭ·Δ
    ϒϩοΫ͢Δॲཧ͕͋ͬͨΒશ෦ࢭ·Δ
    ϒϩοΫͯ͠΋શମ͸ಈ͔͍ͨ͠
    ͦ͜ͰϚϧνεϨουͰ͢Αʂ
    ʢͦ΋ͦ΋Fiber೉͍͠͠ʣ
    Halt
    - Halt if there is a process that blocks other one
    - But want to run a whole system if there is
    - This is good timing to use multi threads

    View full-size slide

  52. ͓͢͢Ί
    γεςϜશମ͸ΞΫλʔϞσϧͰߟ͑Δ
    ΞΫλʔͷத਎͸ϚϧνεϨου
    Recomended way
    - Think about a whole system using Actor Model
    - In this context, Actor is multi thread

    View full-size slide

  53. ͠͹Β͓͘଴͍ͪͩ͘͞
    ✓ ΞΫλʔ͓͞Β͍ͨ͠
    ✓ ͓͢͢Ίͨ͠
    ✓ 'JCFSωλ

    View full-size slide

  54. github/seki/bartender
    Fiber೉ͦ͠͏ͳͷͰ࢖ͬͯΈͨʂ
    selectΛগ͠ந৅Խ͢ΔϑϨʔϜϫʔΫ
    BTW
    - Fiber seems difficult, but i tried.
    - This is a framework to abstract a 'select' a little

    View full-size slide

  55. Bartender::App
    App#[]=(event, fd, callback)
    ίʔϧόοΫͷొ࿥ɻ
    Ϣʔβʔσʔλ͸ͳ͠ɻ⇦ MethodΦϒδΣΫτΛ౉ͤ͹͍͍͡ΌΜ
    App#delete(event, fd)
    App#run
    ϝΠϯϧʔϓ
    App#[]=
    - registers a callback
    - Pass method object

    View full-size slide

  56. Ҏ্ʂ
    [event, fd]ͱϝιουΛ݁ͼ͚ͭΔ͚ͩ
    That's all!
    - That's the point of this framework

    View full-size slide

  57. ReaderͱWriter
    ͜ΕͰ͸ෆศͳͷͰϢʔςΟϦςΟʔΛ
    non-block I/OΛblock෩ʹ͢Δ
    blockͦ͠͏ʹͳͬͨΒ࣮ߦݖΛख์͢
    Fiber.yieldͶ
    - This is not useful so let's provide a utility
    - Block-ish non-blocking I/O
    - If going to block, Fiber yield.

    View full-size slide

  58. Bartender::Reader
    Reader#read(n)
    nΦΫςοτಡΉ
    Reader#read_until(sep="\r\n", chunk_size=8192)
    Reader#readln
    ηύϨʔλ·Ͱʢߦ຤·ͰʣಡΜͰฦ͢

    View full-size slide

  59. Bartender::Reader#read(n)
    def read(n)
    while @buf.bytesize < n
    chunk = _read(n)
    break if chunk.nil? || chunk.empty?
    @buf += chunk
    end
    @buf.slice!(0, n)
    end

    View full-size slide

  60. readͷ಺ଆͷ_read͕ϛι
    Θ͔Γʹ͍͚͘Ͳ͕͜͜Πέϝϯ
    The _read insight head is the point
    - seems difficult, but hang in there.

    View full-size slide

  61. Bartender::Reader#_read(n)
    def _read(n)
    @fd.read_nonblock(n)
    rescue IO::WaitReadable
    select_readable
    retry
    end
    def select_readable
    @bartender[:read, @fd] = Fiber.current.method(:resume)
    Fiber.yield
    ensure
    @bartender.delete(:read, @fd)
    end

    View full-size slide

  62. Bartender::Reader#_read(n)
    def _read(n)
    @fd.read_nonblock(n)
    rescue IO::WaitReadable
    select_readable
    retry
    end
    def select_readable
    @bartender[:read, @fd] = Fiber.current.method(:resume)
    Fiber.yield
    ensure
    @bartender.delete(:read, @fd)
    end
    Method object

    View full-size slide

  63. Bartender::Reader#_read(n)
    def _read(n)
    @fd.read_nonblock(n)
    rescue IO::WaitReadable
    select_readable
    retry
    end
    def select_readable
    @bartender[:read, @fd] = Fiber.current.method(:resume)
    Fiber.yield
    ensure
    @bartender.delete(:read, @fd)
    end
    back to Bartender

    View full-size slide

  64. Bartender::Reader#_read(n)
    def _read(n)
    @fd.read_nonblock(n)
    rescue IO::WaitReadable
    select_readable
    retry
    end
    def select_readable
    @bartender[:read, @fd] = Fiber.current.method(:resume)
    Fiber.yield
    ensure
    @bartender.delete(:read, @fd)
    end
    Unregister callback

    View full-size slide

  65. dRubyϓϩτίϧ
    ࣮ݧ༻ΫϥΠΞϯτॻ͘ͷ͕໘౗
    dRubyͷϓϩτίϧΛ࿩ͤΔαʔόΛॻ͜͏
    Writing a client for experiment is tough
    So let's write a server that understands dRuby protocol

    View full-size slide

  66. dRubyϓϩτίϧ
    ಈ͍ͨʂ͕͢͞ࢲʂ
    I did it! It works!

    View full-size slide

  67. Bartender::Server
    class Server
    def initialize(bartender, port, &blk)
    @bartender = bartender
    @server = TCPServer.new(port)
    @bartender[:read, @server] = self.method(:on_accept)
    @blk = blk
    end
    def on_accept
    client = @server.accept
    reader = Reader.new(@bartender, client)
    writer = Writer.new(@bartender, client)
    fiber = Fiber.new do
    @blk.yield(reader, writer)
    end
    fiber.resume
    end
    end
    not important

    View full-size slide

  68. DRbEchoServer
    def initialize(bartender, port)
    @rdv = Rdv.new
    Bartender::Server.new(bartender, port) do |reader, writer|
    begin
    while true
    _, msg, argv = req_drb(reader)
    case msg
    when 'push'
    value = @rdv.push(argv)
    else
    value = @rdv.pop
    end
    reply_drb(writer, true, value)
    end
    rescue
    p $!
    end
    end
    end not important

    View full-size slide

  69. DRbEchoServer
    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
    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
    ブロックを気にせずreadし
    まくる
    Don't care about I/O blocking and context switch
    Just read it sequentially

    View full-size slide

  70. BartenderͰͷFiberͷ࢖͍ํ
    I/OͷϒϩοΫͷࡍʹ࣮ߦݖΛख์͢
    ϑϨʔϜϫʔΫ͕׬ྃΛଊ͑ͯ࠶։͢Δ
    - Fiber.yield when I/O block happens
    - The framework catches its finish and then resumes the fiber

    View full-size slide

  71. ղܾ͠ͳ͔ͬͨ͜ͱ
    ͦͷϝιου͸௕͍ॲཧΛ͢Δͷʁ
    ஌Δํ๏͕ͳ͍
    Θ͔ͬͨͱ͜ΖͰͲ͏͍͍͔ͯ͠Θ͔Βͳ͍
    εϨουͷํ͕Ϛγ
    Things not solved yet
    - Halt when calling the method that blocks
    - Thread is relatively better

    View full-size slide

  72. ͠͹Β͓͘଴͍ͪͩ͘͞
    ✓ #BSUFOEFSࣗຫ
    ✓ ΤʔςϧΛ࡞Ζ͏

    View full-size slide

  73. ࣗ෼ͷΤʔςϧΛ࡞Ζ͏
    Queue
    TupleSpace
    Write your own Ether

    View full-size slide

  74. શһQueue࣋ͬͯΔ
    ΦϒδΣΫτΛThreadͱQueueͰแΜͰΈͨ
    ΦϒδΣΫτ͕QueueΛ࣋ͭ
    ϝιουݺͼग़͠ΛશͯQueue΁
    ௚ྻԽ
    Let all objects have a queue

    View full-size slide

  75. ࣗ෼༻Queue

    View full-size slide

  76. method_missing
    class ActorsOffice
    def initialize(actor)
    @queue = Queue.new
    @thread = Thread.new(actor) do
    catch(actor) do
    while true
    msg, arg, blk = @queue.pop
    actor.__send__(msg, *arg, &blk)
    end
    end
    end
    end
    def __thread__; @thread; end
    def method_missing(m, *a, &b)
    @queue.push([m, a, b])
    end
    end

    View full-size slide

  77. ॻ͍͚ͨͲ
    ࢖Θͳ͔ͬͨʂ
    ͳΜͰ΋௚ྻԽ͍ͨ͠ਓ޲͚
    I wrote, but not used.
    It's just for those who like to serialize

    View full-size slide

  78. தԝूݖܕ
    Rinda::TupleSpace
    Centralized structure

    View full-size slide

  79. தԝूݖܕ
    Centralized structure

    View full-size slide

  80. ether = Rinda::TupleSpace
    _, message = ether.take([:oso_matz, nil])
    ether.write([message[:from], { :reply => "Hi!" })
    message = {
    :from => :choro_matz, :greeting => "Hello, World."
    }
    ether.write([:oso_matz, message])
    ether.write([:todo_matz, message])

    View full-size slide

  81. ·͋ಈ͘
    dRubyͱ૊Έ߹ΘͤΕ͹ϓϩηεؒ΋ಈ͘Α
    Α͘࢖ͬͯΔ
    Yes, it works.
    - You can run it between processes / machines by using dRuby
    - I use it, frequently

    View full-size slide

  82. ΤʔςϧΛॻ͍ͯؾ͍ͮͨ
    ΞΫλʔͱΤʔςϧͷؔ܎΋ΞΫλʔʁ
    Ϟσϧͱͯ͠ͷΞΫλʔ͸Ͳ͜ʹͰ΋͋Δͷ
    Ͱ͸ʂ
    As you may notice when listening to my talk, the relationship between
    Actor and Ether may be Actor Model, too

    View full-size slide

  83. ·ͱΊ
    Ϟσϧͱͯ͠ͷΞΫλʔΛ͓͞Β͍
    ΑΓྑ͍εϨου͡Όͳ͍ؾ෼Λڞ༗
    Ͱ͖ͨʁ
    Summary
    - Recap what Actor Model is
    - Feel like it's not just a better Thread, is it?

    View full-size slide

  84. ӳ༁͋Γ͕ͱ
    u
    @yasulab @akira_nise @tenderlove

    View full-size slide