Distributed Systems
vs.
Compositionality
Dr. Roland Kuhn
@rolandkuhn — CTO of Actyx
Caveat:
This presentation shows unreleased APIs!
Weird starting point:
π calculus
What is a calculus?
• syntax for writing down a computation
• reduction rules for evaluating the syntax
4
π calculus: the syntax
5
Robin Milner et al, 1992
⇡ ::=
8
><
>:
x(y) receive y along x
xhyi send y along x
⌧ unobservable action
(1)
P ::=
X
i2I
⇡i.Pi P1|P2 new a P !P 0 (2)
π calculus: the reductions
6
TAU : ⌧.P + M ! P (3)
REACT : x(y).P + M xhzi.Q + N ! z/y P Q (4)
PAR :
P ! P0
P|Q ! P0|Q
(5)
RES :
P ! P0
new x P ! new x P0
(6)
STRUCT :
P ! P0
Q ! Q0
if P ⌘ Q ^ P0
⌘ Q0
(7)
Robin Milner et al, 1992
An example reduction
7
P = new z
⇣
(xhyi.0 + z(w).whyi.0) x(u).uhvi.0 xhzi.0
⌘
possibility	1
possibility	2
An example reduction
8
P = new z
⇣
0 yhvi.0 xhzi.0
⌘
An example reduction
9
P = new z
⇣
(xhyi.0 + z(w).whyi.0) x(u).uhvi.0 xhzi.0
⌘
possibility	2
An example reduction
10
P = new z
⇣
(xhyi.0 + z(w).whyi.0) zhvi.0 0
⌘
only	one	possibility
An example reduction
11
P = new z
⇣
vhyi.0 0 0
⌘
An example reduction
12
P = vhyi.0
There’s more!
• structural congruence allows symbolic
manipulation
• rename, reorder sums, expand recursion, …
• bi-simulation describes functional equivalence
13
So, what is a calculus?
• a way to write down computations
• a means to reason about computations
• a tool to compose computations
14
Composition
Composition in the π calculus
• you can
• run computations sequentially
• run computations concurrently
• synchronize concurrent computations
16
Composing processes
17
new cA
⇣
Pclient PserviceA
⌘
channel	where	
serviceA	is	reachable
will	send	to	cA	and	
eventually	react	to	
response
will	react	to	cA	and	
eventually	send	back	
a	response
We need protocols!
What is a protocol?
• defines a communication discipline:
• who can send what kind of message, and when
• which kinds of message to expect, and when
• each distributed process must adhere to the
common protocol
• a global protocol can be checked for safety
19
Session types
• Session: a unit of conversation
• Session Type: the structure of a conversation,

a sequence of interactions in a

communication-centric program model
• originally only binary sessions,

multiparty session types introduced 2008
• primitives are

sending, receiving, sequence, choice, recursion



20
http://groups.inf.ed.ac.uk/abcd/
Session types example
21
Sreqresp = !Request(params) . ?Response(result)
Sreqresp = ?Request(params) . !Response(result)
But is it safe? Does it compose?
22
Pclient PserviceA PbackendA
PserviceB PbackendB
Protocols don’t compose!
• at least not in general, as far as we know
• some cases are (mostly?) okay
• non-cyclic
• non-interacting
• what a bummer!

⟹ let’s find a smaller problem to solve
23
Composing Actor Behavior
Behavior composition
25
new cinternal
⇣
PserviceA PclientB
⌘
26
case class DoStuff(stuff: Stuff)
case class DoIt(it: It)
case class DoneSuccessfully(result: Result)
class MyActor(receptionist: ActorRef) extends Actor {
override def preStart(): Unit = receptionist ! Register
def receive = initializing
def initializing: Receive = {
case Registered =>
// do stuff
context.become(running)
}
def running: Receive = {
case DoStuff(stuff) =>
context.actorOf(Props[Child]) ! DoIt(???)
context.become(waitingForResult(stuff))
}
def waitingForResult(stuff: Stuff): Receive = {
case DoneSuccessfully(result) =>
// do stuff, e.g. replying
context.become(running)
}
}
We need reusable composable
behavior snippets!
Radical idea: π calculus within!
• idea sparked while listening to Alex Prokopec
• create DSL inspired by π calculus
• lifted representation of asynchronous actions
• combinators for sequential & parallel composition
28
What does it look like?
29
π calculus Akka Typed Sessions
new c P val serverChannel = channel[Command](128)
P initialize: Process[ActorRef[Request]]
π.P for {

backend ← initialize

server ← register(backend)

} yield run(server, backend)
P|Q fork(task): Process[Unit]

read(serverChannel) race timeout(1.second)

getThingA join getThingB
x(y) read(serverChannel): Process[Command]
x❬y❭ serverChannel.ref ! msg

(synchronous send operation not there, yet)
Example of a Server Process
30
def run(server: Channel[ServerCommand],
backend: ActorRef[BackendCommand])
: Process[Nothing] =
for {
cmd ← read(server)
} yield cmd match {
case GetIt(which, replyTo) =>
val spinOff =
talkWithBackend(which, backend)
.foreach(thing => replyTo ! GotIt(thing.weird))
fork(spinOff race timeout(5.seconds))
.then(run(server, backend))
}
Example of a Server Process
31
def talkWithBackend(which: String,
backend: ActorRef[BackendCommand])
: Process[TheThing] = {
val code = channel[Code](1)
val thing = channel[TheThing](1)
backend ! GetThingCode(0xdeadbeefcafeL, code.ref)
for {
c ← readAndSeal(code)
} yield {
c.magicChest ! GetTheThing(which, thing.ref)
readAndSeal(thing)
}
}
What does this have to do with Akka?
• Akka Typed Behavior to interpret Process
• channel reference is a lean child ActorRef
• this closes the gap between the Actor Model
and CSP/π
• Actors have stable identity but only one channel
• anonymous Processes have multiple channels

(with identity)
32
Outlook
Tracking effects
• lifted representation of Process allows
tracking of effects
• embedding of session type in π calculus exists
• verify Process against a session type
34
Irresponsible Speculation
35
// Effects is similar to HList (but a tree)
trait Process[T, E <: Effects] {
def map[U, UE <: Effects](f: T => Process[U, UE])
:Process[U, UE :*: E]
def join[U, UE <: Effects](p: Process[U, UE])
:Process[(T, U), UE :+: E]
def race // ???
}
def read[T](c: Channel[T]): Process[T, Recv[c.type]]
def write[T](ref: ActorRef[T]): Process[T, Send[ref.type]]
def fork[T, TE <: Effects](p: Process[T, TE])
: Process[Unit, NoEffect :|: TE]
Current State
• behaviors can be composed both sequentially
and concurrently
• effects are not yet tracked
• Scribble generator for Scala not yet there
• theoretical work at Imperial College, London

(Prof. Nobuko Yoshida & Alceste Scalas)
36
©Actyx AG 2016 – All Rights Reserved

Distributed systems vs compositionality

  • 1.
    Distributed Systems vs. Compositionality Dr. RolandKuhn @rolandkuhn — CTO of Actyx
  • 2.
  • 3.
  • 4.
    What is acalculus? • syntax for writing down a computation • reduction rules for evaluating the syntax 4
  • 5.
    π calculus: thesyntax 5 Robin Milner et al, 1992 ⇡ ::= 8 >< >: x(y) receive y along x xhyi send y along x ⌧ unobservable action (1) P ::= X i2I ⇡i.Pi P1|P2 new a P !P 0 (2)
  • 6.
    π calculus: thereductions 6 TAU : ⌧.P + M ! P (3) REACT : x(y).P + M xhzi.Q + N ! z/y P Q (4) PAR : P ! P0 P|Q ! P0|Q (5) RES : P ! P0 new x P ! new x P0 (6) STRUCT : P ! P0 Q ! Q0 if P ⌘ Q ^ P0 ⌘ Q0 (7) Robin Milner et al, 1992
  • 7.
    An example reduction 7 P= new z ⇣ (xhyi.0 + z(w).whyi.0) x(u).uhvi.0 xhzi.0 ⌘ possibility 1 possibility 2
  • 8.
    An example reduction 8 P= new z ⇣ 0 yhvi.0 xhzi.0 ⌘
  • 9.
    An example reduction 9 P= new z ⇣ (xhyi.0 + z(w).whyi.0) x(u).uhvi.0 xhzi.0 ⌘ possibility 2
  • 10.
    An example reduction 10 P= new z ⇣ (xhyi.0 + z(w).whyi.0) zhvi.0 0 ⌘ only one possibility
  • 11.
    An example reduction 11 P= new z ⇣ vhyi.0 0 0 ⌘
  • 12.
  • 13.
    There’s more! • structuralcongruence allows symbolic manipulation • rename, reorder sums, expand recursion, … • bi-simulation describes functional equivalence 13
  • 14.
    So, what isa calculus? • a way to write down computations • a means to reason about computations • a tool to compose computations 14
  • 15.
  • 16.
    Composition in theπ calculus • you can • run computations sequentially • run computations concurrently • synchronize concurrent computations 16
  • 17.
    Composing processes 17 new cA ⇣ PclientPserviceA ⌘ channel where serviceA is reachable will send to cA and eventually react to response will react to cA and eventually send back a response
  • 18.
  • 19.
    What is aprotocol? • defines a communication discipline: • who can send what kind of message, and when • which kinds of message to expect, and when • each distributed process must adhere to the common protocol • a global protocol can be checked for safety 19
  • 20.
    Session types • Session:a unit of conversation • Session Type: the structure of a conversation,
 a sequence of interactions in a
 communication-centric program model • originally only binary sessions,
 multiparty session types introduced 2008 • primitives are
 sending, receiving, sequence, choice, recursion
 
 20 http://groups.inf.ed.ac.uk/abcd/
  • 21.
    Session types example 21 Sreqresp= !Request(params) . ?Response(result) Sreqresp = ?Request(params) . !Response(result)
  • 22.
    But is itsafe? Does it compose? 22 Pclient PserviceA PbackendA PserviceB PbackendB
  • 23.
    Protocols don’t compose! •at least not in general, as far as we know • some cases are (mostly?) okay • non-cyclic • non-interacting • what a bummer!
 ⟹ let’s find a smaller problem to solve 23
  • 24.
  • 25.
  • 26.
    26 case class DoStuff(stuff:Stuff) case class DoIt(it: It) case class DoneSuccessfully(result: Result) class MyActor(receptionist: ActorRef) extends Actor { override def preStart(): Unit = receptionist ! Register def receive = initializing def initializing: Receive = { case Registered => // do stuff context.become(running) } def running: Receive = { case DoStuff(stuff) => context.actorOf(Props[Child]) ! DoIt(???) context.become(waitingForResult(stuff)) } def waitingForResult(stuff: Stuff): Receive = { case DoneSuccessfully(result) => // do stuff, e.g. replying context.become(running) } }
  • 27.
    We need reusablecomposable behavior snippets!
  • 28.
    Radical idea: πcalculus within! • idea sparked while listening to Alex Prokopec • create DSL inspired by π calculus • lifted representation of asynchronous actions • combinators for sequential & parallel composition 28
  • 29.
    What does itlook like? 29 π calculus Akka Typed Sessions new c P val serverChannel = channel[Command](128) P initialize: Process[ActorRef[Request]] π.P for {
 backend ← initialize
 server ← register(backend)
 } yield run(server, backend) P|Q fork(task): Process[Unit]
 read(serverChannel) race timeout(1.second)
 getThingA join getThingB x(y) read(serverChannel): Process[Command] x❬y❭ serverChannel.ref ! msg
 (synchronous send operation not there, yet)
  • 30.
    Example of aServer Process 30 def run(server: Channel[ServerCommand], backend: ActorRef[BackendCommand]) : Process[Nothing] = for { cmd ← read(server) } yield cmd match { case GetIt(which, replyTo) => val spinOff = talkWithBackend(which, backend) .foreach(thing => replyTo ! GotIt(thing.weird)) fork(spinOff race timeout(5.seconds)) .then(run(server, backend)) }
  • 31.
    Example of aServer Process 31 def talkWithBackend(which: String, backend: ActorRef[BackendCommand]) : Process[TheThing] = { val code = channel[Code](1) val thing = channel[TheThing](1) backend ! GetThingCode(0xdeadbeefcafeL, code.ref) for { c ← readAndSeal(code) } yield { c.magicChest ! GetTheThing(which, thing.ref) readAndSeal(thing) } }
  • 32.
    What does thishave to do with Akka? • Akka Typed Behavior to interpret Process • channel reference is a lean child ActorRef • this closes the gap between the Actor Model and CSP/π • Actors have stable identity but only one channel • anonymous Processes have multiple channels
 (with identity) 32
  • 33.
  • 34.
    Tracking effects • liftedrepresentation of Process allows tracking of effects • embedding of session type in π calculus exists • verify Process against a session type 34
  • 35.
    Irresponsible Speculation 35 // Effectsis similar to HList (but a tree) trait Process[T, E <: Effects] { def map[U, UE <: Effects](f: T => Process[U, UE]) :Process[U, UE :*: E] def join[U, UE <: Effects](p: Process[U, UE]) :Process[(T, U), UE :+: E] def race // ??? } def read[T](c: Channel[T]): Process[T, Recv[c.type]] def write[T](ref: ActorRef[T]): Process[T, Send[ref.type]] def fork[T, TE <: Effects](p: Process[T, TE]) : Process[Unit, NoEffect :|: TE]
  • 36.
    Current State • behaviorscan be composed both sequentially and concurrently • effects are not yet tracked • Scribble generator for Scala not yet there • theoretical work at Imperial College, London
 (Prof. Nobuko Yoshida & Alceste Scalas) 36
  • 37.
    ©Actyx AG 2016– All Rights Reserved