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
210
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
2.1k
WAT JavaScript Date
othree
3
2.1k
Modern HTML Email Development
othree
3
2.7k
MRT & GIT
othree
1
2.2k
YAJS.vim and Vim Syntax Highlight
othree
1
2.9k
Web Trends to 2015
othree
4
320
Transducer
othree
9
3k
HITCON 11 Photographer
othree
4
490
fetch is the new XHR
othree
6
3.6k
Other Decks in Technology
See All in Technology
【M3】攻めのセキュリティの実践!プロアクティブなセキュリティ対策の実践事例
axelmizu
0
170
大規模モノレポの秩序管理 失速しない多言語化フロントエンドの運用 / JSConf JP 2025
shoota
0
250
「データ無い! 腹立つ! 推論する!」から 「データ無い! 腹立つ! データを作る」へ チームでデータを作り、育てられるようにするまで / How can we create, use, and maintain data ourselves?
moznion
8
4.5k
pmconf 2025 大阪「生成AI時代に未来を切り開くためのプロダクト戦略:圧倒的生産性を実現するためのプロダクトサイクロン」 / Product Cyclone for the Outstanding Productivity
yamamuteki
1
150
AI × クラウドで シイタケの収穫時期を判定してみた
lamaglama39
1
360
アジャイル社内普及ご近所さんマップを作ろう / Let's create an agile neighborhood map
psj59129
1
130
AI時代の戦略的アーキテクチャ 〜Adaptable AI をアーキテクチャで実現する〜 / Enabling Adaptable AI Through Strategic Architecture
bitkey
PRO
7
2.4k
ABEMAのCM配信を支えるスケーラブルな分散カウンタの実装
hono0130
4
960
FFMとJVMの実装から学ぶJavaのインテグリティ
kazumura
0
130
OSだってコンテナしたい❗Image Modeが切り拓くLinux OS運用の新時代
tsukaman
0
100
AIを前提に、業務を”再構築”せよ IVRyの9ヶ月にわたる挑戦と未来の働き方 (BTCONJP2025)
yueda256
1
780
生成AI時代に若手エンジニアが最初に覚えるべき内容と、その学習法
starfish719
2
500
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Building an army of robots
kneath
306
46k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
Thoughts on Productivity
jonyablonski
73
4.9k
How to Ace a Technical Interview
jacobian
280
24k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
34
2.3k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Practical Orchestrator
shlominoach
190
11k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
658
61k
Making Projects Easy
brettharned
120
6.5k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
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