Slide 1

Slide 1 text

Actor Model ؆հ John Lin

Slide 2

Slide 2 text

• Ұݸ༻ိ႔ཧฒߦӡࢉతఔࣜ໛ܕ • 1973 ೥༝ Carl Hewitt, Peter Bishop & Richard Steiger ఏग़ɻ • ༝ၷେ෦෼૊੒ Actor & message • ෆधཁ೚Կಛผత async featureɼՄҎࡏၚ౷త blocking ؀ڥத መ࡞ɻ What is Actor Model

Slide 3

Slide 3 text

• ఔࣜӡࢉతᄸݩɻ༗ࣗݾᘐཱతهԱᱪ࿨ӡࢉೳྗɻ • ༗ᘐಛత໊ࢠʢ஍ᅿʣ • ՄҎ၏Լ໘ز݅ࣄɻ • ઀Ꮕ㘤ଉ • 㗞ੜ৽త actorɻ • ૹ㘤ଉڅଖଞ actorɻ • վᏓࣗݾతهԱᱪʢվᏓߦҝʣ Actor

Slide 4

Slide 4 text

• Actor ೭ؒޓ૬ߏ௨తػ੍ɻ • Actor ՄҎૹmessageڅଖଞత actorɻ • ୠੋ୞ೳᏅࣗݾత messageɻ • Obj-C message send ༗ 87% ૾ Message

Slide 5

Slide 5 text

• Erisson language • ༻ࡏి৴ަ׵ػதɻ • ॏࢹฒߦӡࢉɻߴՄ༻ੑɻ Erlang

Slide 6

Slide 6 text

Erlang Actor

Slide 7

Slide 7 text

Erlang Actor

Slide 8

Slide 8 text

• 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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

• ᔒ༗ 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

Slide 11

Slide 11 text

• ߟྀԼ໘తྫࢠɼݺڣ 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

Slide 12

Slide 12 text

• ᙛ actor ։࢝ await త࣌ީɼՄҎࣥߦଖଞ(҃ಉҰݸʣ methodɻ ෆ။ඃ block ɻ • ໵ՄҎࡏ actor ཫ໘ݺڣࣗݾతଖଞ methodɼෆ။ඃ blockɻ Reentrant

Slide 13

Slide 13 text

• ࡏ༗ 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

Slide 14

Slide 14 text

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 ଄੒త໰୊

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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>

Slide 17

Slide 17 text

• ᙛ actor ։࢝ await త࣌ީɼՄҎࣥߦଖଞ(҃ಉҰݸʣ methodɻ ෆ။ඃ block ɻ • ໵ՄҎࡏ actor ཫ໘ݺڣࣗݾతଖଞ methodɼෆ။ඃ blockɻ • ࠷޷ੋࡏ࠷ޙ࠶Ұ࣍मվvariableɻ • ༗㠥֎త proposal ཁ၏ non-reentrant actorɻ Reentrant

Slide 18

Slide 18 text

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.

Slide 19

Slide 19 text

• 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

Slide 20

Slide 20 text

Actor vs Golang Channel