Attached and Detached Closures in Actors Dave Clarke, Kiko Fernandez-Reyes, Elias Castegren Tobias Wrigstad, Albert Mingkun Yang KTH Royal Institute of Uppsala University Technology
What Tobias Said • The Encore programming language • Object orientation + actors • Guarantees safe sharing of objects between actors • Handling both concurrency and parallelism in the actor model • Lessons learned & Open questions ! 2
This Talk • State-capturing closures in an actor-setting • Current and future solutions in Encore • Terminology for discussing closure semantics ! 3
We All Like Actors ! 4
We All Like Actors ! 5
Some of Us Like Functional Programming • Functional programming plays nicely with the actor model • Algebraic data-types 흺 x : t .x + 42 da t a L i s t a = • Immutability | N il • Higher-order functions | C ons a (L i s t a) • … • Examples include Erlang and Elixir ! 6
⇒ Some of Us Also Like Object Orientation • Actor programming is familiar to OO programmers • Actors can be thought of as ”active” objects • Sending Messages ≈ Calling Methods • OO relies heavily on mutable state and aliasing ⇒ Sharing ! 7
Some of Us Also Like Object Orientation • Actor programming is familiar to OO programmers • Actors can be thought of as ”active” objects • Sending Messages ≈ Calling Methods • OO relies heavily on mutable state and aliasing ⇒ Sharing ⇒ Data-races ⇒ Loss of actor isolation! ! 8
Making Actors and OO Play Nice • Capability-based languages/systems, type systems • Encore • Pony [Clebsch et al.] • LaCasa (for Scala) [Haller & Loiko] • Joelle [Östlund et al.] • Relying on delegation of method calls • e.g. far references in AmbientTalk [Dedecker et al.] • Relying on copying of (passive) objects • e.g. Proactive [Caromel et al.] ! 9
Encore Primer/Reminder a ctiv e cl ass A ct o r Actors introduced via classes v a r c oun t : int v a l o t he r : A ct o r Message passing de f wo rk () : unit v a l f u t = t h i s .o t he r ! c ompu t e() v a l r esu lt = g e t f u t Synchronisation via futures t h i s .p ri n t ( r esu lt ) end de f p ri n t ( v : Da t a) : unit t h i s . c oun t += 1 … // P ri n t t he v a l ue end … end ! 10
Capabilities for Concurrency Control • Every reference carries a capability (tracked by the type system) • li nea r — No aliases, transfer semantics • l o c a l — Local to its creating actor • r ead — Read-only reference (no mutable aliases) • a ctiv e — Actor reference (asynchronous communication) • … ! 11
Capabilities for Concurrency Control • Every reference carries a capability (tracked by the type system) • li nea r — No aliases, transfer semantics • l o c a l — Local to its creating actor • r ead — Read-only reference (no mutable aliases) • a ctiv e — Actor reference (asynchronous communication) • … l o c a l cl ass C oun t e r v a r c = new C oun t e r a ct o r ! f oo( c ) v a r c n t : i n t Can’t share local object … end v a r l = new L i s t li nea r cl ass L i s t a ct o r ! ba r ( c onsume l ) v a r fir s t : Node … ! 11 end
Avoiding Blocking on Futures (Chaining) a ctiv e cl ass A ct o r v a r c oun t : int v a l o t he r : A ct o r de f wo rk () : unit de f wo rk _nob l o ck () : unit v a l f u t = t h i s .o t he r ! c ompu t e() v a l f u t = t h i s.o t he r ! c ompu t e() Induces waiting times f u t ~~> v a l r esu lt = g e t f u t f un ( v : Da t a) = > t h i s .p ri n t ( v ) t h i s .p ri n t ( r esu lt ) end end Who runs this closure? de f p ri n t ( v : Da t a) : unit t h i s . c oun t += 1 … // P ri n t t he v a l ue end … end ! 12
Who Runs a Closure? de f wo rk _nob l o ck () : unit v a l f u t = t h i s.o t he r ! c ompu t e() f u t ~~> f un ( v : Da t a) = > t h i s .p ri n t ( v ) end F 흺 ! 13
Who Runs a Closure? de f wo rk _nob l o ck () : unit de f wo rk _nob l o ck 2() : unit v a l f u t = t h i s.o t he r ! c ompu t e() v a l f u t = t h i s.o t he r ! c ompu t e() f u t ~~> f u t ~~> f un ( v : Da t a) = > t h i s ! p ri n t ( v ) f un ( v : Da t a) = > t h i s .p ri n t ( v ) end end F 흺 ! 14
Attached and Detached Closures • An attached closure is always run by its creating actor • A detached closure can be run by any actor 흺 ! 15
Attached and Detached Closures • An attached closure is always run by its creating actor • A detached closure can be run by any actor 흺 ! 15
Attached and Detached Closures • An attached closure is always run by its creating actor • A detached closure can be run by any actor 흺 f un ( v : Da t a) = > t h i s .p ri n t ( v ) ! 15
Closures and Capabilities in Encore • A closure mirrors the (non-sharable) capabilities it captures f un ( v : Da t a) = > t h i s .p ri n t ( v ) : (Da t a -> unit ) l o c a l ! 16
Closures and Capabilities in Encore • A closure mirrors the (non-sharable) capabilities it captures f un ( v : Da t a) = > t h i s .p ri n t ( v ) : (Da t a -> unit ) l o c a l ! 16
Closures and Capabilities in Encore • A closure mirrors the (non-sharable) capabilities it captures l o c a l f un ( v : Da t a) = > t h i s .p ri n t ( v ) : (Da t a -> unit ) f un ( v : Da t a) = > t h i s ! p ri n t ( v ) : (Da t a -> unit ) a ctiv e ! 17
Closures and Capabilities in Encore • A closure mirrors the (non-sharable) capabilities it captures l o c a l f un ( v : Da t a) = > t h i s .p ri n t ( v ) : (Da t a -> unit ) f un ( v : Da t a) = > t h i s ! p ri n t ( v ) : (Da t a -> unit ) a ctiv e ! 17
Closures and Capabilities in Encore • A closure mirrors the (non-sharable) capabilities it captures l o c a l f un ( v : Da t a) = > t h i s .p ri n t ( v ) : (Da t a -> unit ) f un ( v : Da t a) = > t h i s ! p ri n t ( v ) : (Da t a -> unit ) ! 17
Labeling Closures as Attached/Detached de f wo rk _nob l o ck () : unit v a l f u t = t h i s.o t he r ! c ompu t e() f u t ~~> Captures local state: f un ( v : Da t a) = > t h i s .p ri n t ( v ) must be attached! end de f wo rk _nob l o ck 2() : unit v a l f u t = t h i s.o t he r ! c ompu t e() f u t ~~> Only captures safe state: f un ( v : Da t a) = > t h i s ! p ri n t ( v ) can be detached! end ! 18
Categorising Closures • Tetheredness ∈ {attached, detached} • Execution ∈ {synchronous, asynchronous} • Sharability ∈ {sharable, unsharable} Execution Sharability Tetheredness ! 19
Categorising Closures Tetheredness Execution Sharability Comment Attached Synchronous Sharable Explicitly pass back closure to owner Attached Synchronous Unsharable Current Encore implementation Attached Asynchronous Sharable Encore, when chaining Attached Asynchronous Unsharable Delaying operations Detached Synchronous Sharable Safe ”normal” closures in Encore Detached Synchronous Unsharable Not useful? Detached Asynchronous Sharable Task paralellism Detached Asynchronous Unsharable Not useful? ! 20
Categorising Closures Tetheredness Execution Sharability Comment Attached Synchronous Sharable Explicitly pass back closure to owner Attached Synchronous Unsharable Current Encore implementation Attached Asynchronous Sharable Encore, when chaining Attached Asynchronous Unsharable Delaying operations Detached Synchronous Sharable Safe ”normal” closures in Encore Detached Synchronous Unsharable Not useful? Detached Asynchronous Sharable Task paralellism Detached Asynchronous Unsharable Not useful? f un ( v : Da t a) = > v . f oo() + 1 f un ( v : Da t a) = > t h i s ! p ri n t ( v ) ! 20
Categorising Closures Tetheredness Execution Sharability Comment Attached Synchronous Sharable Explicitly pass back closure to owner Attached Synchronous Unsharable Current Encore implementation Attached Asynchronous Sharable Encore, when chaining Attached Asynchronous Unsharable Delaying operations Detached Synchronous Sharable Safe ”normal” closures in Encore Detached Synchronous Unsharable Not useful? Detached Asynchronous Sharable Task paralellism Detached Asynchronous Unsharable Not useful? f un ( v : Da t a) = > t h i s .p ri n t ( v ) ! 21
Categorising Closures Tetheredness Execution Sharability Comment Attached Synchronous Sharable Explicitly pass back closure to owner Attached Synchronous Unsharable Current Encore implementation Attached Asynchronous Sharable Encore, when chaining Attached Asynchronous Unsharable Delaying operations Detached Synchronous Sharable Safe ”normal” closures in Encore Detached Synchronous Unsharable Not useful? Detached Asynchronous Sharable Task paralellism Detached Asynchronous Unsharable Not useful? f u t ~~> f un ( v : Da t a) = > t h i s .p ri n t ( v ) ! 22
Categorising Closures Tetheredness Execution Sharability Comment Attached Synchronous Sharable Explicitly pass back closure to owner Attached Synchronous Unsharable Current Encore implementation Attached Asynchronous Sharable Encore, when chaining Attached Asynchronous Unsharable Delaying operations Detached Synchronous Sharable Safe ”normal” closures in Encore Detached Synchronous Unsharable Not useful? Detached Asynchronous Sharable Task paralellism Detached Asynchronous Unsharable Not useful? as y n c (x. f oo()) ! 23
Recommend
More recommend