Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
272 lines (164 sloc) 7.04 KB
Javascript Concurrency Patterns
RefactorU Guest Speaker
23 Sep 2014
Tags: javascript, concurrency, patterns, async, promises, flow-control, callbacks
Jon Eisen
Code Typist, Rafflecopter
jon@joneisen.me
http://joneisen.me/
@jm_eisen
* Overview
1. *What*is*Concurrency?*
2. *Concurrency*Basics*
- Asynchronous Javascript
- Flow Control: `async` and Promises
3. *Concurrency*Patterns*
- Events
- Finite Worker Queues
4. *Recap*
.html code/jquery.html
####################### Introduction #######################
* Javascript Concurrency Patterns
** Intro to Concurrency
.image img/meme-concurrency.jpg _ 350
* What is Concurrency?
- It's not parallelism
- Although it _enables_ parallelism
- If you have only one processor, your program can still be concurrent but it cannot be parallel.
(Above points from [[http://talks.golang.org/2012/concurrency.slide][Go Concurrency Patterns]] by Rob Pike, 2012)
* Single-threaded concurrency
- Single thread means a single CPU thread
- Can't run two calculations at once
- But we can _wait_ on two things at once!
If you're building a system with concurrency, any type of system, what are the things you might use or see?
Answer: *Concurrency*Patterns*
####################### Javascript Basics #######################
* Javascript Concurrency Basics
** First Steps
.image img/write_all_the_code_in_javascript1.jpg _ 500
* Not Concurrent
.play code/single-thread-not-concurrent.js /START/,/END/
This isn't concurrent because the `chat` function never returns.
* Now Concurrent
.play code/single-thread-concurrency.js /START/,/END/
This _is_ concurrent because we ask the javascript engine to notify us every time interval.
####################### Flow Control #######################
* Javascript Concurrency Basics
** Flow Control
.image img/meme-refactor.jpg _ 400
* Wait. What is Flow Control?
.image img/parallel_flow.png _ 500
*A*Complicated*Definition:* The organization and act of performing heterogeneous asynchronous tasks concurrently, accounting for dependencies between tasks.
*A*Simpler*Definition:* Running some things in parallel and some things in series.
*More*Simpler*Definition:* Programming.
* Flow Control Use Case
Flow control is used *all*the*time*.
I use flow control every day I program javascript.
- Flow control is how _tasks_ are run.
- It is _not_ a system architecture.
* async
.code code/async.html /START/,/END/
`async` brings flexibility and organization to asynchronous tasks.
.link https://npmjs.org/package/async
.html code/async.html
* Promises
.code code/promises.html /START/,/END/
Promises offer an alternate way to do flow control.
.link https://npmjs.org/package/q
.html code/promises.html
* Example: Asynchronous Map
Imagine we have to retrieve a list of user objects that are friends with a user. First we must look up the user's friends list. Then we must retrieve his/her friend's user objects from the database. This is called _asynchronous_mapping_.
This is a super common pattern in javascript. It is basically an extension of flow control.
* Example: Asynchronous Map - Database Walking
.code code/dbwalk.js /STARTASYNC/,/ENDASYNC/
.code code/dbwalk.js /STARTPROMISE/,/ENDPROMISE/
####################### Events #######################
* Javascript Concurrency Patterns
** Events
.image img/meme-jquery.jpg _ 350
* Events Use Case
*Low*Level:* Node and the browser use events at the lowest level of their engines (called the _event_loop_).
*Environment*Interaction:*
- DOM events like `change`, `load`, `input`, `keydown`, `touchstart`, etc
- Many basic node objects use events (files, streams, http requests)
*High*Level:*
- A _messaging_ system where decoupled parts can communicate through an event emitter intermediary
- Events can enable third-party plugins to work with your libraries
* Events, Simply
.image img/events.png _ 600
* Events, Simply, Again
.code code/simple_events.html
.html code/simple_events.html
Click the button!
* Browser User Interactions using jQuery
.code code/jquery_events.html /START/,/END/
.html code/jquery_events.html
Submit the form!
* Game Loop using EventEmitter
.html code/game_events.html
* Game Loop using EventEmitter
.code code/game_events.html /START/,/END/
Events allow for declarative concurrency and decoupled communication.
####################### Middleware #######################
#* Javascript Concurrency Patterns
#** Middleware
#.image img/middlewaredoge.jpeg _ 350
#
#* express
#
#The [[http://expressjs.com/][express]] webserver uses middleware all over the place!
#
#.code code/express.js /START1/,/END1/
#.play code/express.js /START2/,/END2/
#
#* Middleware Use Case
#
# Middleware is essentially `async.series` with some context.
#
#But `express` middleware is so common!
#
#Some other uses exist, but are far less common.
####################### Finite Worker Queue #######################
* Javascript Concurrency Patterns
** Finite Worker Queue
.image img/meme-queue.jpg _ 350
* Queues Use Case
Queues are a great way to decouple asking for work and doing work.
- Makes a system respond fast
- Allows a lot of work to be done without impacting response time
- Helps keep track of work to be done
Finite worker advantages:
- Rate limiting (***cough*** twitter's API ***cough***).
- Reduce race conditions between tasks
* Finite Worker Queue
.code code/web_crawler.js /START1/,/END1/
* Web Crawler using FiniteQueue
.play code/web_crawler.js /START2/,/END2/
Note use of `npm` modules [[http://npmjs.org/package/cheerio][cheerio]] and [[http://npmjs.org/package/request][request]].
* Web Crawler using async.queue
.play code/web_crawler_async.js /START2/,/END2/
Note use of `npm` modules [[http://npmjs.org/package/cheerio][cheerio]], [[http://npmjs.org/package/async][async]] and [[http://npmjs.org/package/request][request]].
* Wait! What about an INFINITE Worker Queue?
This is a trivial case!
.code code/infinite_worker_queue.js /START1/,/END1/
.play code/infinite_worker_queue.js /START2/,/END2/
####################### Ending #######################
* Javascript Concurrency Patterns
** Ending
.image img/meme-compiles.jpg _ 450
* Recap
- Flow Control for tasks (async & promises)
- Events (EventEmitter & jQuery)
- Finite Worker Queue (custom & async)
Choose the pattern _right_ for your situation!
* More Reading!
Javascript Concurrency I didn't talk about:
- [[https://github.com/substack/stream-handbook][Node Streams]]
- [[https://github.com/Rafflecopter/node-relyq][Using Redis as a distributed queue]]
- [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*][ES6 Generators]]
- [[https://blog.safaribooksonline.com/2014/03/10/express-js-middleware-demystified/][Express Middleware]]
Cool Concurrency Things (read: Not Javascript)
- [[https://talks.golang.org/2012/concurrency.slide#1][Rob Pike's "Go Concurrency Patterns"]]
- [[https://github.com/clojure/core.async][Clojure's core.async (works with Clojurescript)]]
- [[http://www.erlang.org/doc/design_principles/users_guide.html][Erlang OTP]]
- [[http://zguide.zeromq.org/page:all][0MQ Guide - A great book on Distributed Systems Patterns with 0MQ]]