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

CSP

othree
February 14, 2015

 CSP

Communicating Sequential Processes

othree

February 14, 2015
Tweet

More Decks by othree

Other Decks in Technology

Transcript

  1. CSP othree

  2. Communicating Sequential Processes

  3. https://medium.com/@addyosmani/javascript-application-architecture-on-the-road-to-2015-d8125811101b

  4. 1978

  5. 1985

  6. What is CSP • Communication between processes • Born to

    be async • Using channel
  7. Process B Process A

  8. Process B Process A Channel msg

  9. Process B Process A msg PUT

  10. Process B Process A msg

  11. Process B Process A msg TAKE

  12. Process B Process A Channel msg

  13. Implements Go Clojure goroutine core.async

  14. https://speakerdeck.com/kachayev/channels-and-concurrency-go-clojure-erlang-haskell

  15. Go Example

  16. package main import "fmt" func main() { messages := make(chan

    string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
  17. package main import "fmt" func main() { messages := make(chan

    string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
  18. Short Variable Declarations • Declare variable • and assign value

    at the same time :=
  19. package main import "fmt" func main() { messages := make(chan

    string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
  20. Receive Operator • Receive message • From channel • or

    channel receive message • Also imply direction of message <-
  21. package main import "fmt" func main() { messages := make(chan

    string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
  22. None
  23. Go Example II

  24. package main import "fmt" import "time" func worker(done chan bool)

    { fmt.Print("working...") time.Sleep(time.Second) fmt.Println("done") done <- true } func main() { done := make(chan bool, 1) go worker(done) <-done }
  25. package main import "fmt" import "time" func worker(done chan bool)

    { fmt.Print("working...") time.Sleep(time.Second) fmt.Println("done") done <- true } func main() { done := make(chan bool, 1) go worker(done) <-done }
  26. package main import "fmt" import "time" func worker(done chan bool)

    { fmt.Print("working...") time.Sleep(time.Second) fmt.Println("done") done <- true } func main() { done := make(chan bool, 1) go worker(done) <-done }
  27. Go Statement • Execute function as independent process(goroutine) go

  28. None
  29. Go Pingpong Example

  30. package main import "fmt" import "time" type Ball struct{ hits

    int } func player(name string, table chan *Ball) { for { ball := <-table ball.hits++ fmt.Println(name, ball.hits) time.Sleep(100 * time.Millisecond) table <- ball } }
  31. package main import "fmt" import "time" type Ball struct{ hits

    int } func player(name string, table chan *Ball) { for { ball := <-table ball.hits++ fmt.Println(name, ball.hits) time.Sleep(100 * time.Millisecond) table <- ball } }
  32. player • Receive ball from channel • Hit ball(+1) •

    Sleep • Send ball back
  33. func main() { table := make(chan *Ball) go player("ping", table)

    go player("pong", table) table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball }
  34. func main() { table := make(chan *Ball) go player("ping", table)

    go player("pong", table) table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball }
  35. func main() { table := make(chan *Ball) go player("ping", table)

    go player("pong", table) table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball }
  36. func main() { table := make(chan *Ball) go player("ping", table)

    go player("pong", table) table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball }
  37. Process Channel Message players table Ball

  38. player pong player ping table Ball

  39. None
  40. Key Requirement • Channel • Ability to wait(idle) message

  41. Channel • First class object • First in first out

    • Accessible across processes
  42. Idle • Not able to idle in JavaScript • Use

    recursive function call can emulate, bad performance • ES6 have async function
  43. async function

  44. function* foo(){ var index = 0; while (index <= 2)

    // when index reaches 3, // yield's done will be true // and its value will be undefined; yield index++; }
  45. var iterator = foo(); console.log(iterator.next()); // { value:0, done:false }

    console.log(iterator.next()); // { value:1, done:false } console.log(iterator.next()); // { value:2, done:false } console.log(iterator.next()); // { value:undefined, done:true }
  46. yield • Function will stop and return on yield •

    Next call will exec from last yield • Sort of idle
  47. js-csp

  48. js-csp • by Nguyễn Tuấn Anh • Major implementation •

    Use async function • Also implement `go`, dispatcher…etc
  49. None
  50. Pingpong Example

  51. function* player(name, table) { while (true) { var ball =

    yield csp.take(table); if (ball === csp.CLOSED) { console.log(name + ": table's gone"); return; } ball.hits += 1; console.log(name + " " + ball.hits); yield csp.timeout(100); yield csp.put(table, ball); } }
  52. function* player(name, table) { while (true) { var ball =

    yield csp.take(table); if (ball === csp.CLOSED) { console.log(name + ": table's gone"); return; } ball.hits += 1; console.log(name + " " + ball.hits); yield csp.timeout(100); yield csp.put(table, ball); } } func player(name string, table chan *Ball) { for { ball := <-table ball.hits++ fmt.Println(name, ball.hits) time.Sleep(100 * time.Millisecond) table <- ball } } Go
  53. csp.go(function* () { var table = csp.chan(); csp.go(player, ["ping", table]);

    csp.go(player, ["pong", table]); yield csp.put(table, {hits: 0}); yield csp.timeout(1000); table.close(); });
  54. csp.go(function* () { var table = csp.chan(); csp.go(player, ["ping", table]);

    csp.go(player, ["pong", table]); yield csp.put(table, {hits: 0}); yield csp.timeout(1000); table.close(); }); func main() { table := make(chan *Ball) go player("ping", table) go player("pong", table) table <- new(Ball) time.Sleep(1 * time.Second) <-table } Go
  55. csp.go(player, ["ping", table]); go player("ping", table) yield csp.put(table, {hits: 0});

    table <- new(Ball) yield csp.take(table); <-table
  56. csp.go(function* () { func main() { var table = csp.chan();

    table := make(chan *Ball) yield csp.timeout(1000); time.Sleep(1 * time.Second)
  57. js-csp • Easy to port Go program • yield is

    annoying
  58. What Can Use CSP • Sequential async data • Event

  59. Real World Event • Might have multiple event handler on

    single event
  60. Channel Message • Only can take once

  61. operations alt mult mix merge onto pipe split close timeout

    https://clojure.github.io/core.async/
  62. mult • one to many

  63. var csp = require("./src/csp"); var mult = csp.operations.mult; var buffers

    = csp.buffers; var channel = csp.chan(); var m = mult(channel); https://github.com/ubolonton/js-csp/issues/31#issuecomment-68089526
  64. var csp = require("./src/csp"); var mult = csp.operations.mult; var buffers

    = csp.buffers; var channel = csp.chan(); var m = mult(channel);
  65. csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val =

    yield csp.take(out); console.log('process 1', val); }); csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val = yield csp.take(out); console.log('process 2', val); });
  66. csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val =

    yield csp.take(out); console.log('process 1', val); }); csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val = yield csp.take(out); console.log('process 2', val); });
  67. csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val =

    yield csp.take(out); console.log('process 1', val); }); csp.go(function*() { var out = mult.tap(m, csp.chan(buffers.sliding(1))); var val = yield csp.take(out); console.log('process 2', val); });
  68. csp.putAsync(channel, 42);

  69. not stable on js-csp

  70. Cons • Annoying yield • Not stable operations* • Lib

    size • Not support Web Worker
  71. js-csp • Syntax from Go • Operations from Clojure •

    Have disadvantages • Can use transducer from Clojure
  72. https://www.youtube.com/watch?v=7rDsRXj9-cU