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

Actor model 簡介

Actor model 簡介

Johnlin

May 04, 2021
Tweet

More Decks by Johnlin

Other Decks in Programming

Transcript

  1. Actor Model ؆հ
    John Lin

    View full-size slide

  2. • Ұݸ༻ိ႔ཧฒߦӡࢉతఔࣜ໛ܕ

    • 1973 ೥༝ Carl Hewitt, Peter Bishop & Richard Steiger ఏग़ɻ

    • ༝ၷେ෦෼૊੒ Actor & message

    • ෆधཁ೚Կಛผత async featureɼՄҎࡏၚ౷త blocking ؀ڥத
    መ࡞ɻ
    What is Actor Model

    View full-size slide

  3. • ఔࣜӡࢉతᄸݩɻ༗ࣗݾᘐཱతهԱᱪ࿨ӡࢉೳྗɻ

    • ༗ᘐಛత໊ࢠʢ஍ᅿʣ

    • ՄҎ၏Լ໘ز݅ࣄɻ

    • ઀Ꮕ㘤ଉ

    • 㗞ੜ৽త actorɻ

    • ૹ㘤ଉڅଖଞ actorɻ

    • վᏓࣗݾతهԱᱪʢվᏓߦҝʣ
    Actor

    View full-size slide

  4. • Actor ೭ؒޓ૬ߏ௨తػ੍ɻ

    • Actor ՄҎૹmessageڅଖଞత actorɻ

    • ୠੋ୞ೳᏅࣗݾత messageɻ

    • Obj-C message send ༗ 87% ૾
    Message

    View full-size slide

  5. • Erisson language

    • ༻ࡏి৴ަ׵ػதɻ

    • ॏࢹฒߦӡࢉɻߴՄ༻ੑɻ
    Erlang

    View full-size slide

  6. Erlang Actor

    View full-size slide

  7. Erlang Actor

    View full-size slide

  8. • SE-0306 Actors መ࡞ྃ Actorɻୠੋ࿨ Actor model ฒෆ׬શ૬ಉɻ

    • جຊ্बੋ㚎ݐྃ mutex త classɻॴ༗త var ౎ඃ mutex อޢɻ

    actor BankAccount {
    let accountNumber: Int
    var balance: Double
    init(accountNumber: Int, initialDeposit: Double) {
    self.accountNumber = accountNumber
    self.balance = initialDeposit
    }
    }
    Swift Actor

    View full-size slide

  9. protocol Actor : AnyObject, Sendable { }
    • ໨લᔒ༗ඞཁత methodɻ೭ޙత proposal ။Ճɻ

    • ՄҎ์ࡏ፤ိఆٛಛԽత protocol

    protocol DataProcessible: Actor { // only actor types can conform to this
    var data: Data { get } // actor-isolated to self
    }
    extension DataProcessible {
    func compressData() -> Data { // actor-isolated to self
    }
    }
    actor MyProcessor : DataProcessible {
    var data: Data // okay, actor-isolated to self
    func doSomething() {
    let newData = compressData() // calling actor-isolated method on self
    }
    }
    Actor type

    View full-size slide

  10. • ᔒ༗ message passingɼ୞༗ typed async method callɻ

    • ୞༗ࡏ method ཫ࠽ೳमվ varɻ

    extension BankAccount {
    func transfer(amount: Double, to other:
    BankAccount) async throws {
    assert(amount > 0)
    if amount > balance {
    throw BankError.insufficientFunds
    }
    balance = balance - amount
    await other.deposit(amount: amount)
    }
    }
    Swift Actor message passing

    View full-size slide

  11. • ߟྀԼ໘తྫࢠɼݺڣ syn ՄҎਖ਼ৗӡ࡞䆩ʁ

    actor TCP {
    func syn(to other:TCP) async {
    await other.synAck(self)
    }
    func synAck(to other:TCP) async {
    await other.ack(self)
    }
    func ack(to other:TCP) async {
    }
    }
    Reentrant

    View full-size slide

  12. • ᙛ actor ։࢝ await త࣌ީɼՄҎࣥߦଖଞ(҃ಉҰݸʣ methodɻ
    ෆ။ඃ block ɻ

    • ໵ՄҎࡏ actor ཫ໘ݺڣࣗݾతଖଞ methodɼෆ။ඃ blockɻ
    Reentrant

    View full-size slide

  13. • ࡏ༗ reentrant త৘گԼੋ။ಈతɻ await త࣌ީՄҎ၏ଖଞతࣄɻ

    actor TCP {
    func syn(to actor2:TCP) async {
    await actor2.synAck(self)
    }
    func synAck(to actor1:TCP) async {
    await actor1.ack(self)
    }
    func ack(to actor2:TCP) async {
    }
    }
    Reentrant

    View full-size slide

  14. actor Person {
    let friend: Friend
    // actor-isolated opinion
    var opinion: Judgment = .noIdea
    func thinkOfGoodIdea() async -> Decision {
    opinion = .goodIdea // <1>
    await friend.tell(opinion, heldBy: self) // <2>
    return opinion // 🤨 // <3>
    }
    func thinkOfBadIdea() async -> Decision {
    opinion = .badIdea // <4>
    await friend.tell(opinion, heldBy: self) // <5>
    return opinion // 🤨 // <6>
    }
    }
    Reentrant ଄੒త໰୊

    View full-size slide

  15. Reentrant ଄੒త໰୊
    let goodThink = detach { await
    person.thinkOfGoodIdea() } // runs async
    let badThink = detach { await
    person.thinkOfBadIdea() } // runs async
    let shouldBeGood = await goodThink.get()
    let shouldBeBad = await badThink.get()
    await shouldBeGood // could be .goodIdea
    or .badIdea ☠
    await shouldBeBad

    View full-size slide

  16. actor Person {
    let friend: Friend
    // actor-isolated opinion
    var opinion: Judgment = .noIdea
    func thinkOfGoodIdea() async -> Decision {
    opinion = .goodIdea // <1>
    await friend.tell(opinion, heldBy: self) // <2>
    return opinion // 🤨 // <3>
    }
    func thinkOfBadIdea() async -> Decision {
    opinion = .badIdea // <4>
    await friend.tell(opinion, heldBy: self) // <5>
    return opinion // 🤨 // <6>
    }
    }
    opinion = .goodIdea // <1>
    // suspend: await friend.tell(...) // <2>
    opinion = .badIdea // | <4> (!)
    // suspend: await friend.tell(...) // | <5>
    // resume: await friend.tell(...) // <2>
    return opinion // <3>
    // resume: await friend.tell(...) // <5>
    return opinion // <6>

    View full-size slide

  17. • ᙛ actor ։࢝ await త࣌ީɼՄҎࣥߦଖଞ(҃ಉҰݸʣ methodɻ
    ෆ။ඃ block ɻ

    • ໵ՄҎࡏ actor ཫ໘ݺڣࣗݾతଖଞ methodɼෆ။ඃ blockɻ

    • ࠷޷ੋࡏ࠷ޙ࠶Ұ࣍मվvariableɻ

    • ༗㠥֎త proposal ཁ၏ non-reentrant actorɻ
    Reentrant

    View full-size slide

  18. Swift Actor vs Erlang Actor
    Local
    Value
    Message
    passing
    Mailbox Reply Reentrant
    Swift Yes
    Static,

    Compiler
    invoke
    methods
    No,
    compiler
    invoke
    methods
    Automatic,

    Typed
    Yes. Can
    be called
    from self
    Erlang Yes
    Dynamic

    Send
    anything
    Yes
    Manual,

    Need to
    know
    sender
    No.

    Receive
    blocks
    actor.

    View full-size slide

  19. • Reference:

    • https://www.brianstorti.com/the-actor-model/

    • Wiki

    • Joe Armstrong's thesis

    • Swift Evolution

    • https://learnyousomeerlang.com/the-hitchhikers-guide-to-
    concurrency#dont-panic
    Q&A

    View full-size slide

  20. Actor vs Golang Channel

    View full-size slide