Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CSP
Search
othree
February 14, 2015
Technology
1
200
CSP
Communicating Sequential Processes
othree
February 14, 2015
Tweet
Share
More Decks by othree
See All by othree
How GitHub Supports Vim License Detection, The Five Years Journey
othree
1
2k
WAT JavaScript Date
othree
3
2k
Modern HTML Email Development
othree
3
2.6k
MRT & GIT
othree
1
2.2k
YAJS.vim and Vim Syntax Highlight
othree
1
2.8k
Web Trends to 2015
othree
4
310
Transducer
othree
9
2.9k
HITCON 11 Photographer
othree
4
480
fetch is the new XHR
othree
6
3.5k
Other Decks in Technology
See All in Technology
Information Architecture Recommoning: How Standardization Enables Differentiation
angioia
0
140
Kafka vs. Pulsar: Performance Evaluation by Petabyte-Scale Streaming Platform Providers
lycorptech_jp
PRO
1
290
データプレーンプログラミングとは? DPU&スイッチASICの開発経験から語る
ebiken
PRO
1
300
TypeScript をより型安全に扱うプラクティス #TSKaigi #TSKaigi2025_kataritai
bengo4com
0
2.1k
Houtou.pm #1
papix
0
970
Eight Engineering Unit 紹介資料
sansan33
PRO
0
3.4k
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
760
不安定だったテストが信頼を取り戻すまで / The Road to Trustworthy Tests
katawara
0
120
ソフトウェアテストのAI活用_ver1.20
fumisuke
0
200
実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜
joker1007
3
810
大手企業のAIツール導入の壁を越えて:サイバーエージェントのCursor活用戦略
gunta
34
14k
SwiftUI Transaction を徹底活用!ZOZOTOWN UI開発での活用事例
tsuzuki817
1
120
Featured
See All Featured
It's Worth the Effort
3n
184
28k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
We Have a Design System, Now What?
morganepeng
52
7.6k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
19
1.3k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
Mobile First: as difficult as doing things right
swwweet
223
9.6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Facilitating Awesome Meetings
lara
54
6.4k
Transcript
CSP othree
Communicating Sequential Processes
https://medium.com/@addyosmani/javascript-application-architecture-on-the-road-to-2015-d8125811101b
1978
1985
What is CSP • Communication between processes • Born to
be async • Using channel
Process B Process A
Process B Process A Channel msg
Process B Process A msg PUT
Process B Process A msg
Process B Process A msg TAKE
Process B Process A Channel msg
Implements Go Clojure goroutine core.async
https://speakerdeck.com/kachayev/channels-and-concurrency-go-clojure-erlang-haskell
Go Example
package main import "fmt" func main() { messages := make(chan
string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
package main import "fmt" func main() { messages := make(chan
string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
Short Variable Declarations • Declare variable • and assign value
at the same time :=
package main import "fmt" func main() { messages := make(chan
string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
Receive Operator • Receive message • From channel • or
channel receive message • Also imply direction of message <-
package main import "fmt" func main() { messages := make(chan
string, 1) messages <- "ping" msg := <-messages fmt.Println(msg) }
None
Go Example II
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 }
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 }
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 }
Go Statement • Execute function as independent process(goroutine) go
None
Go Pingpong Example
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 } }
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 } }
player • Receive ball from channel • Hit ball(+1) •
Sleep • Send ball back
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 }
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 }
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 }
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 }
Process Channel Message players table Ball
player pong player ping table Ball
None
Key Requirement • Channel • Ability to wait(idle) message
Channel • First class object • First in first out
• Accessible across processes
Idle • Not able to idle in JavaScript • Use
recursive function call can emulate, bad performance • ES6 have async function
async function
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++; }
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 }
yield • Function will stop and return on yield •
Next call will exec from last yield • Sort of idle
js-csp
js-csp • by Nguyễn Tuấn Anh • Major implementation •
Use async function • Also implement `go`, dispatcher…etc
None
Pingpong Example
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); } }
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
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(); });
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
csp.go(player, ["ping", table]); go player("ping", table) yield csp.put(table, {hits: 0});
table <- new(Ball) yield csp.take(table); <-table
csp.go(function* () { func main() { var table = csp.chan();
table := make(chan *Ball) yield csp.timeout(1000); time.Sleep(1 * time.Second)
js-csp • Easy to port Go program • yield is
annoying
What Can Use CSP • Sequential async data • Event
Real World Event • Might have multiple event handler on
single event
Channel Message • Only can take once
operations alt mult mix merge onto pipe split close timeout
https://clojure.github.io/core.async/
mult • one to many
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
var csp = require("./src/csp"); var mult = csp.operations.mult; var buffers
= csp.buffers; var channel = csp.chan(); var m = mult(channel);
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); });
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); });
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); });
csp.putAsync(channel, 42);
not stable on js-csp
Cons • Annoying yield • Not stable operations* • Lib
size • Not support Web Worker
js-csp • Syntax from Go • Operations from Clojure •
Have disadvantages • Can use transducer from Clojure
https://www.youtube.com/watch?v=7rDsRXj9-cU