Wix R&D meetup;
CSP & Scala: theory and
implementation.
https://github.com/rssh/scala-gopher
Ruslan Shevchenko
<ruslan@shevchenko.kiev.ua>
https://github.com/rssh
@rssh1
2. Outline
❖ Theory & History
❖ CSP = Communication Sequence Processes
❖ !-calculus (CCS = Calculus of Communicating System)
❖ Languages: (Occam,Limbo, Go[Clojure, Scala, … ])
❖ Main constructions / idioms, how they looks
❖ Channels, Selectors, Transputers
❖ Implementation Techniques
3. Theory & History
❖ If you familiar with basic concepts, skip to slide 8
❖ Just show me scala API: skip to slide 14
4. Theory & History
❖ CPS = Communication Sequence Processes.
❖ CSS = Calculus of Communicating System.
❖ 1978 First CSP Paper by Tony Hoar.
❖ 1980. CSS by Robert Milner. (Algebraic Processes)
❖ 1985 CSP formalism (influenced by CSS) in CSP Book
❖ http://www.usingcsp.com/
❖ 1992 !-calculus [CSS + Channels] (Robert Milner, Joachim Parrow,
David Walker)
❖ …. (large family of Process Algebras, including Actor Model, ACP, )
5. CSP Notation(basic)
❖ (A, B, C … ) — processes,
❖ (x, y, z … ) — events
❖ atomic: x , STOP, BEEP, or c.v (channel/value)
❖ c!v - send v to channel c (after this c.v happens)
❖ c?v - receive v from channel c (wait until c.v)
❖ trace(…) — sequence of events.
6. CSP Notation(basic)
// after event
Operations on processes:
// fix point (loops, recursion
// interleave concurrently
// choice, if a then P if b then Q
// seq
7. CSP Notation(examples)
COPY(left,right)=
left right
P1 P2
Q1 Q2
P1 P2
Q1 Q2
8. Occam language
William Occam, 1287-1347
‘Occam razor’ principle
Occam language. (1983)
INT x, y:
SEQ
x := 4
y := (x + 1)
CHAN INT c:
PAR
some.procedure (x, y, c!)
another.procedure (c?)
y := 5
braces via indentation. (before python)
minimal language. (processor constructors)
9. Occam language
❖ created by INMOS
❖ targeted Transputers CHIP architecture (bare metal)
❖ latest dialect: occam-! [1996]
❖ extensions from !-calculus
❖ (more dynamic, channels can be send via channels)
❖ http://concurrency.cc — occam for Aurdino.
10. Inferno, Limbo, Go
❖ Unix, Plan9, Inferno: [At&t; Bell labs; vita nuova]
❖ http://www.vitanuova.com/inferno/
❖ Limbo … C-like language + channels + buffered channels.
❖ Go … channels as in Limbo (Go roots is from hell is not a metaphor)
Sean Forward
David Leo Presotto
Rob Pike
Dennis M. Ritchie
Ken Thompson
11. CPS in Limbo/Go/Scala: main constructions
❖ processes: operator for spawning new lightweight
process.
❖ channels: can be unbuffered (synchronised) or buffered
❖ unbuffered — writer wait until reader start to work
❖ buffered — if channel buffer is not full, writer not
blocked
❖ selector: wait for few events (channel), eval first.
12. Go: simple code example
func fibonacci(c chan int, quit chan bool) {
go {
x, y := 0, 1
for (){
select {
case c <- x :
x, y = y, x+y
case q<-quit:
break;
}
}
close(c)
}
}
c = make(chan int);
quit= make(chan bool);
fibonacci(c,quit)
for i := range c {
fmt.Println(i)
if (i > 2000) {
quit <- true
}
}
Go
13. Go: simple code example
func fibonacci(c chan int, quit chan bool) {
go {
x, y := 0, 1
for (){
select {
case c <- x :
x, y = y, x+y
case q<- quit:
break;
}
}
close(c)
}
}
c = make(chan int);
quit= make(chan bool);
fibonacci(c,quit)
for i := range c {
fmt.Println(i)
if (i > 2000) {
quit <- true
}
}
Go
14. scala-gopher
❖ Akka extension + Macros on top of SIP22-async
❖ Integrate CSP primitives and scala concurrency
❖ Provide:
❖ asynchronous API inside general control-flow
❖ pseudo-synchronous API inside go{ .. } or async{ ..}
blocks
def fibonacci(c: Channel[Int], quit: Channel[Boolean]): Future[Unit] = go {
var (x, y) = (0, 1)
select.forever{
case x : c.write =>
val z = x
x = y; y = x+z
case q: quit.read =>
CurrentFlowTermination.exit(())
}
c.close()
}
15. Scala: simple code example (direct translation)
val c = makeChannel[Int]()
val quit= makeChannel[Boolean]();
val f = fibonacci(c,quit)
for ( i <- c) {
System.out.print(i)
if (i > N) {
quit.awrite( true )
Scala
16. Scala-gopher: main constructions
❖ Gopher: Akka extension.
❖ go[T](body: T): Future[T]
❖ inside body we can use pseudosynchronous API
❖ defer
❖ select [forever, once] => [choice]
❖ case matching macros; for statement, fold, ..
❖ channels
❖ channels/ Input[X]/Output[X] / collection API
val gopherApi = GopherAPI(actorsSystem)
import gopherApi._
def fibonacci(c: Channel[Int], quit: Channel[Boolean]): Future[Unit] = go {
var (x, y) = (0, 1)
select.forever{
case x : c.write =>
val z = x
x = y; y = x+z
case q: quit.read =>
CurrentFlowTermination.exit(())
}
c.close()
}
}
17. Scala: simple code example (direct translation)
val c = makeChannel[Int]()
val quit= makeChannel[Boolean]();
val f = fibonacci(c,quit)
for ( i <- c) {
System.out.print(i)
if (i > N) {
quit.awrite( true )
Scala
(mutable var, WTF ?)
def fibonacci(c: Channel[Int], quit: Channel[Boolean]): Future[Unit] = go {
select.fold((0,1)){ case ((x,y),s) =>
s match {
case x : c.write =>
(y, x+y)
case q: quit.read =>
CurrentFlowTermination.exit((x,y))
}
}
c.close()
}
18. Scala: simple code example (fold)
val c = makeChannel[Int]()
val quit= makeChannel[Boolean]();
val f = fibonacci(c,quit)
for ( i <- c) {
System.out.print(i)
if (i > N) {
quit.awrite( true )
Scala
def fibonacci(c: Channel[Int], quit: Channel[Boolean]): Future[Unit] = go {
val (x,y) = select.fold((0,1)){ case ((x,y),s) =>
s match {
case x : c.write =>
(y, x+y)
case q: quit.read =>
CurrentFlowTermination.exit((x,y))
}
}
c.close()
}
19. Scala: simple code example (fold)
val c = makeChannel[Int]()
val quit= makeChannel[Boolean]();
val f = fibonacci(c,quit)
for ( i <- c) {
System.out.print(i)
if (i > N) {
quit.awrite( true )
Scala
def fibonacci(c: Channel[Int], quit: Channel[Boolean]): Future[(Int,Int)] =
select.afold((0,1)){ case ((x,y),s) =>
s match {
case x : c.write =>
(y, x+y)
case q: quit.read =>
c.close()
CurrentFlowTermination.exit((x,y))
}
}
20. Scala: simple code example (аfold)
val c = makeChannel[Int]()
val quit= makeChannel[Boolean]();
val f = fibonacci(c,quit)
for ( i <- c) {
System.out.print(i)
if (i > N) {
quit.awrite( true )
Scala
s match {
case x : c.write =>
(y, x+y)
case q: quit.read =>
c.close()
CurrentFlowTermination.exit((x,y))
}
21. scala-gopher: select
Scala
s match {
case z : c.write if (z == 1) =>
……..
case x: Int if (x == future.read()) =>
}
//special syntax
//writing expressions
//reading from expressions
22. scala-gopher: select de-‘macro’
select.forever{
case x: channel1.read => (do-something-1)
case y: channel2.read => (do-something-2)
case z: channel3.write => (do-something-3)
case _ => (do-somethig-4)
}
{ val s = select.createForeverSelectorBuilder()
s.reading(channel1, x => (do-something-1))
s.reading(channel2, y => (do-something-2))
s.write(channel3,z,….)
s.idle(do-something-4)
s.run()
}
23. scala-gopher: select de-‘macro’
s.reading(channel1, x => (do-something-1))
s.onRead(channel1, x => {
implicit f1: FlowTermination = s.flowTermination
implicit e1: ExecutionContext => s.executionContext
scala.async.Async.async( transfer(do-something-1) )
}
24. scala-gopher: select functionality
❖ select functionality
❖ wrap callbacks, supplied by user
❖ to guarantee than only one branch of select match
is running
❖ to provide reaction on flowTermination
❖ pass one to channels/inputs/outpus
25. scala-gopher: Input/Output.
❖ Input[T] - something, from which we can wait input
❖ callback-based ‘native’ trait.
❖ implementations: channels, futures, collections …
❖ collection-like methods: map, filter, fold, zip,
append, merge…
aread(): Future[T]
read: T = await(aread)
<~ = read.
26. scala-gopher: Input/Output.
❖ Output[T] - something, where we can send value
❖ callback-based ‘native’ trait.
❖ implementations: channels, promises, actor-s…
awrite(v:T): Future[T]
write(t): T = await(awrite(t))
~> = write.
27. scala-gopher: Timeouts
val (in, inTimeouts) = in.withTimeout(1 minute)
val (out, outTimeouts) = out.withTimeout(10 minutes)
select.fold(s0){ (state,selector) =>
selector match {
case x: in.read => out.write(x)
case t: inTimeouts.read =>
log(“input timeout”);
case t: outTimeouts.read =>
log(“output timeout”);
}
}
28. Example: broadcast without listener registry
❖ Sender:
❖ create buffered channel for each message
❖ send into this channel: message + channel for next message
❖ can report value of channel for next message
❖ Receiver:
❖ read message from channel,
❖ put one back (to allow other readers to receive one)
❖ change channel to listen on just receive.
29. Example: broadcast without listener registry
case class Message[V](
value: Value,
nextChannel: Channel[Message[V]]
)
class Receiver[V](initChannel: Message, handle: V => Unit)
{
val current = makeEffectedChannel(initChannel)
val future = current.forever{ message =>
current write message.value
current := message.nextChannel
go { handle(message.value) }
}
}
30. Example: broadcast without listener registry
class Broadcaster[V]() // single-threaded
{
var last = makeNextChannel
def send(v: V) : Unit = {
val next = makeNextChannel
last write Message(v, next)
last = next
}
def makeReceiver(handler: V => Unit) =
new Receiver(current, next)
def makeNextChannel = makeChannel[Message[V]](1)
}
31. Example: broadcast without listener registry
class Broadcaster[V]()
{
val sendc = makeChannel[V]()
val requestLast = makeChannel[Channel[Channel[Value[V]]]()
val future = select.fold(makeNextChannel){ (last,s) =>
s match {
case v:sendc.read => val next = makeNextChannel
last <~ Message(v,next)
next
case r:requestLast.read =>
r <~ last
last
}
}
def send(v: V) : Unit = sendc.send(v)
31. Example: broadcast without listener registry
class Broadcaster[V]()
{
val sendc = makeChannel[V]()
val requestLast = makeChannel[Channel[Channel[Value[V]]]()
val future = select.fold(makeNextChannel){ (last,s) =>
s match {
case v:sendc.read => val next = makeNextChannel
last <~ Message(v,next)
next
case r:requestLast.read =>
r <~ last
last
}
}
def makeReceiver(handler): Future[Receiver] = go {
val r = makeChannel[Channel[Message[V]]
requestLast <- r
Receiver(await(r.read),handler)
33. CPS / Scala
❖ Test of
❖ essential CPS functionality
❖ dynamic channels
❖ state inside selector folds
❖ More : Transputers
34. Transputers
❖ Structure => schemes.
❖ Entity,
❖ set of input ports
❖ set of output ports
❖ logic
❖ Process/Transputer
35 Transputers.
trait Bingo extends Transputer
{
val inX = inPort[Int]()
val inY = inPort[Int]()
val out = OutPort[String]()
loop {
case x: inX.read =>
val y = inY.read
if (x == y) {
out <~ “Bingo!”
}
}
}
36. Transputers
❖ like actors, but for channels
❖ can be supervised ‘as actors’.
❖ can be connected to each other
val (inX,inY) = (makeChannel[Int](), makeChannel[Int])
val bing = makeTransputer[Bingo]
val acceptor = makeTransputer[Acceptor]
bingo.inX connect inX
bingo.inY connect inY
bingo.out connect acceptor
(bingo + acceptor).start()
37. Transputers
❖ Selector (Custom logic)
❖ Par (|| execution)
❖ Replicate
38. Scala concurrency ecosystem
❖ Future [?]
❖ Erlang-Style ? (actors)
❖ Ozz-Style ? (async [partially])
❖ CPS (gopher)
❖ Rx [?]
❖ Can be used together.
39. Scala-Gopher, problems
❖ async implementation
❖ (buggy, not complete)
❖ need application programmer use macros for providing
‘pseudo synchronised’ API
❖ Need more experience.
❖ // details will be in ScalaUA talk.
40. Questions?
❖ It was about: https://github.com/rssh/scala-gopher
❖ Questions ?
❖ Thanks for attention.

Csp scala wixmeetup2016

  • 1.
    Wix R&D meetup; CSP& Scala: theory and implementation. https://github.com/rssh/scala-gopher Ruslan Shevchenko <ruslan@shevchenko.kiev.ua> https://github.com/rssh @rssh1
  • 2.
    2. Outline ❖ Theory& History ❖ CSP = Communication Sequence Processes ❖ !-calculus (CCS = Calculus of Communicating System) ❖ Languages: (Occam,Limbo, Go[Clojure, Scala, … ]) ❖ Main constructions / idioms, how they looks ❖ Channels, Selectors, Transputers ❖ Implementation Techniques
  • 3.
    3. Theory &History ❖ If you familiar with basic concepts, skip to slide 8 ❖ Just show me scala API: skip to slide 14
  • 4.
    4. Theory &History ❖ CPS = Communication Sequence Processes. ❖ CSS = Calculus of Communicating System. ❖ 1978 First CSP Paper by Tony Hoar. ❖ 1980. CSS by Robert Milner. (Algebraic Processes) ❖ 1985 CSP formalism (influenced by CSS) in CSP Book ❖ http://www.usingcsp.com/ ❖ 1992 !-calculus [CSS + Channels] (Robert Milner, Joachim Parrow, David Walker) ❖ …. (large family of Process Algebras, including Actor Model, ACP, )
  • 5.
    5. CSP Notation(basic) ❖(A, B, C … ) — processes, ❖ (x, y, z … ) — events ❖ atomic: x , STOP, BEEP, or c.v (channel/value) ❖ c!v - send v to channel c (after this c.v happens) ❖ c?v - receive v from channel c (wait until c.v) ❖ trace(…) — sequence of events.
  • 6.
    6. CSP Notation(basic) //after event Operations on processes: // fix point (loops, recursion // interleave concurrently // choice, if a then P if b then Q // seq
  • 7.
  • 8.
    8. Occam language WilliamOccam, 1287-1347 ‘Occam razor’ principle Occam language. (1983) INT x, y: SEQ x := 4 y := (x + 1) CHAN INT c: PAR some.procedure (x, y, c!) another.procedure (c?) y := 5 braces via indentation. (before python) minimal language. (processor constructors)
  • 9.
    9. Occam language ❖created by INMOS ❖ targeted Transputers CHIP architecture (bare metal) ❖ latest dialect: occam-! [1996] ❖ extensions from !-calculus ❖ (more dynamic, channels can be send via channels) ❖ http://concurrency.cc — occam for Aurdino.
  • 10.
    10. Inferno, Limbo,Go ❖ Unix, Plan9, Inferno: [At&t; Bell labs; vita nuova] ❖ http://www.vitanuova.com/inferno/ ❖ Limbo … C-like language + channels + buffered channels. ❖ Go … channels as in Limbo (Go roots is from hell is not a metaphor) Sean Forward David Leo Presotto Rob Pike Dennis M. Ritchie Ken Thompson
  • 11.
    11. CPS inLimbo/Go/Scala: main constructions ❖ processes: operator for spawning new lightweight process. ❖ channels: can be unbuffered (synchronised) or buffered ❖ unbuffered — writer wait until reader start to work ❖ buffered — if channel buffer is not full, writer not blocked ❖ selector: wait for few events (channel), eval first.
  • 12.
    12. Go: simplecode example func fibonacci(c chan int, quit chan bool) { go { x, y := 0, 1 for (){ select { case c <- x : x, y = y, x+y case q<-quit: break; } } close(c) } } c = make(chan int); quit= make(chan bool); fibonacci(c,quit) for i := range c { fmt.Println(i) if (i > 2000) { quit <- true } } Go
  • 13.
    13. Go: simplecode example func fibonacci(c chan int, quit chan bool) { go { x, y := 0, 1 for (){ select { case c <- x : x, y = y, x+y case q<- quit: break; } } close(c) } } c = make(chan int); quit= make(chan bool); fibonacci(c,quit) for i := range c { fmt.Println(i) if (i > 2000) { quit <- true } } Go
  • 14.
    14. scala-gopher ❖ Akkaextension + Macros on top of SIP22-async ❖ Integrate CSP primitives and scala concurrency ❖ Provide: ❖ asynchronous API inside general control-flow ❖ pseudo-synchronous API inside go{ .. } or async{ ..} blocks
  • 15.
    def fibonacci(c: Channel[Int],quit: Channel[Boolean]): Future[Unit] = go { var (x, y) = (0, 1) select.forever{ case x : c.write => val z = x x = y; y = x+z case q: quit.read => CurrentFlowTermination.exit(()) } c.close() } 15. Scala: simple code example (direct translation) val c = makeChannel[Int]() val quit= makeChannel[Boolean](); val f = fibonacci(c,quit) for ( i <- c) { System.out.print(i) if (i > N) { quit.awrite( true ) Scala
  • 16.
    16. Scala-gopher: mainconstructions ❖ Gopher: Akka extension. ❖ go[T](body: T): Future[T] ❖ inside body we can use pseudosynchronous API ❖ defer ❖ select [forever, once] => [choice] ❖ case matching macros; for statement, fold, .. ❖ channels ❖ channels/ Input[X]/Output[X] / collection API val gopherApi = GopherAPI(actorsSystem) import gopherApi._
  • 17.
    def fibonacci(c: Channel[Int],quit: Channel[Boolean]): Future[Unit] = go { var (x, y) = (0, 1) select.forever{ case x : c.write => val z = x x = y; y = x+z case q: quit.read => CurrentFlowTermination.exit(()) } c.close() } } 17. Scala: simple code example (direct translation) val c = makeChannel[Int]() val quit= makeChannel[Boolean](); val f = fibonacci(c,quit) for ( i <- c) { System.out.print(i) if (i > N) { quit.awrite( true ) Scala (mutable var, WTF ?)
  • 18.
    def fibonacci(c: Channel[Int],quit: Channel[Boolean]): Future[Unit] = go { select.fold((0,1)){ case ((x,y),s) => s match { case x : c.write => (y, x+y) case q: quit.read => CurrentFlowTermination.exit((x,y)) } } c.close() } 18. Scala: simple code example (fold) val c = makeChannel[Int]() val quit= makeChannel[Boolean](); val f = fibonacci(c,quit) for ( i <- c) { System.out.print(i) if (i > N) { quit.awrite( true ) Scala
  • 19.
    def fibonacci(c: Channel[Int],quit: Channel[Boolean]): Future[Unit] = go { val (x,y) = select.fold((0,1)){ case ((x,y),s) => s match { case x : c.write => (y, x+y) case q: quit.read => CurrentFlowTermination.exit((x,y)) } } c.close() } 19. Scala: simple code example (fold) val c = makeChannel[Int]() val quit= makeChannel[Boolean](); val f = fibonacci(c,quit) for ( i <- c) { System.out.print(i) if (i > N) { quit.awrite( true ) Scala
  • 20.
    def fibonacci(c: Channel[Int],quit: Channel[Boolean]): Future[(Int,Int)] = select.afold((0,1)){ case ((x,y),s) => s match { case x : c.write => (y, x+y) case q: quit.read => c.close() CurrentFlowTermination.exit((x,y)) } } 20. Scala: simple code example (аfold) val c = makeChannel[Int]() val quit= makeChannel[Boolean](); val f = fibonacci(c,quit) for ( i <- c) { System.out.print(i) if (i > N) { quit.awrite( true ) Scala
  • 21.
    s match { casex : c.write => (y, x+y) case q: quit.read => c.close() CurrentFlowTermination.exit((x,y)) } 21. scala-gopher: select Scala s match { case z : c.write if (z == 1) => …….. case x: Int if (x == future.read()) => } //special syntax //writing expressions //reading from expressions
  • 22.
    22. scala-gopher: selectde-‘macro’ select.forever{ case x: channel1.read => (do-something-1) case y: channel2.read => (do-something-2) case z: channel3.write => (do-something-3) case _ => (do-somethig-4) } { val s = select.createForeverSelectorBuilder() s.reading(channel1, x => (do-something-1)) s.reading(channel2, y => (do-something-2)) s.write(channel3,z,….) s.idle(do-something-4) s.run() }
  • 23.
    23. scala-gopher: selectde-‘macro’ s.reading(channel1, x => (do-something-1)) s.onRead(channel1, x => { implicit f1: FlowTermination = s.flowTermination implicit e1: ExecutionContext => s.executionContext scala.async.Async.async( transfer(do-something-1) ) }
  • 24.
    24. scala-gopher: selectfunctionality ❖ select functionality ❖ wrap callbacks, supplied by user ❖ to guarantee than only one branch of select match is running ❖ to provide reaction on flowTermination ❖ pass one to channels/inputs/outpus
  • 25.
    25. scala-gopher: Input/Output. ❖Input[T] - something, from which we can wait input ❖ callback-based ‘native’ trait. ❖ implementations: channels, futures, collections … ❖ collection-like methods: map, filter, fold, zip, append, merge… aread(): Future[T] read: T = await(aread) <~ = read.
  • 26.
    26. scala-gopher: Input/Output. ❖Output[T] - something, where we can send value ❖ callback-based ‘native’ trait. ❖ implementations: channels, promises, actor-s… awrite(v:T): Future[T] write(t): T = await(awrite(t)) ~> = write.
  • 27.
    27. scala-gopher: Timeouts val(in, inTimeouts) = in.withTimeout(1 minute) val (out, outTimeouts) = out.withTimeout(10 minutes) select.fold(s0){ (state,selector) => selector match { case x: in.read => out.write(x) case t: inTimeouts.read => log(“input timeout”); case t: outTimeouts.read => log(“output timeout”); } }
  • 28.
    28. Example: broadcastwithout listener registry ❖ Sender: ❖ create buffered channel for each message ❖ send into this channel: message + channel for next message ❖ can report value of channel for next message ❖ Receiver: ❖ read message from channel, ❖ put one back (to allow other readers to receive one) ❖ change channel to listen on just receive.
  • 29.
    29. Example: broadcastwithout listener registry case class Message[V]( value: Value, nextChannel: Channel[Message[V]] ) class Receiver[V](initChannel: Message, handle: V => Unit) { val current = makeEffectedChannel(initChannel) val future = current.forever{ message => current write message.value current := message.nextChannel go { handle(message.value) } } }
  • 30.
    30. Example: broadcastwithout listener registry class Broadcaster[V]() // single-threaded { var last = makeNextChannel def send(v: V) : Unit = { val next = makeNextChannel last write Message(v, next) last = next } def makeReceiver(handler: V => Unit) = new Receiver(current, next) def makeNextChannel = makeChannel[Message[V]](1) }
  • 31.
    31. Example: broadcastwithout listener registry class Broadcaster[V]() { val sendc = makeChannel[V]() val requestLast = makeChannel[Channel[Channel[Value[V]]]() val future = select.fold(makeNextChannel){ (last,s) => s match { case v:sendc.read => val next = makeNextChannel last <~ Message(v,next) next case r:requestLast.read => r <~ last last } } def send(v: V) : Unit = sendc.send(v)
  • 32.
    31. Example: broadcastwithout listener registry class Broadcaster[V]() { val sendc = makeChannel[V]() val requestLast = makeChannel[Channel[Channel[Value[V]]]() val future = select.fold(makeNextChannel){ (last,s) => s match { case v:sendc.read => val next = makeNextChannel last <~ Message(v,next) next case r:requestLast.read => r <~ last last } } def makeReceiver(handler): Future[Receiver] = go { val r = makeChannel[Channel[Message[V]] requestLast <- r Receiver(await(r.read),handler)
  • 33.
    33. CPS /Scala ❖ Test of ❖ essential CPS functionality ❖ dynamic channels ❖ state inside selector folds ❖ More : Transputers
  • 34.
    34. Transputers ❖ Structure=> schemes. ❖ Entity, ❖ set of input ports ❖ set of output ports ❖ logic ❖ Process/Transputer
  • 35.
    35 Transputers. trait Bingoextends Transputer { val inX = inPort[Int]() val inY = inPort[Int]() val out = OutPort[String]() loop { case x: inX.read => val y = inY.read if (x == y) { out <~ “Bingo!” } } }
  • 36.
    36. Transputers ❖ likeactors, but for channels ❖ can be supervised ‘as actors’. ❖ can be connected to each other val (inX,inY) = (makeChannel[Int](), makeChannel[Int]) val bing = makeTransputer[Bingo] val acceptor = makeTransputer[Acceptor] bingo.inX connect inX bingo.inY connect inY bingo.out connect acceptor (bingo + acceptor).start()
  • 37.
    37. Transputers ❖ Selector(Custom logic) ❖ Par (|| execution) ❖ Replicate
  • 38.
    38. Scala concurrencyecosystem ❖ Future [?] ❖ Erlang-Style ? (actors) ❖ Ozz-Style ? (async [partially]) ❖ CPS (gopher) ❖ Rx [?] ❖ Can be used together.
  • 39.
    39. Scala-Gopher, problems ❖async implementation ❖ (buggy, not complete) ❖ need application programmer use macros for providing ‘pseudo synchronised’ API ❖ Need more experience. ❖ // details will be in ScalaUA talk.
  • 40.
    40. Questions? ❖ Itwas about: https://github.com/rssh/scala-gopher ❖ Questions ? ❖ Thanks for attention.