CSP

C4ce16f549c450f4759eb37f5d5d1a63?s=47 othree
February 14, 2015

 CSP

Communicating Sequential Processes

C4ce16f549c450f4759eb37f5d5d1a63?s=128

othree

February 14, 2015
Tweet

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