async patterns

or how I learned to stop worrying & love the timer




The Problem




user interfaces are async

javascript rich-apps
swing, flex, java applets




operating systems are async

files, memory, cpu




concurrent systems are async

akka, hadoop, elastic



async is hard


when something is executed asynchronously
you lose control over time & execution:

you can't control when your code gets called
you can't control how your code gets called




The Solution




async event handlers

register some work for some remote action
the work will be done when the event happens
....







or maybe not





callbacks

continually passing around the rest of the work


a simple callback

def onUserClick(event) { // call me maybe  event.getUser().sendGreeting();}
async.register("user-click", onUserClick);


there's some work to be done
we'll register it to happen on user click


what if looking up the user was asynchronous?


def onUserClick(event) {
def onUserFound(user) { user.sendGreeting(); };
async.register("find-user", onUserFound);}

async.register("user-click", onUserClick);

"continuation passing style"
also known as the pyramid of doom
async version of russian nesting dolls

callback hell

saveKingdom(function(kingdom) {
kingdom.fightBattle(function(battle) { battle.getMessage(function(message) { message.getRider(function(rider) { rider.getHorse(function(horse) { horse.getShoe(function(shoe) { shoe.getNail(function(nail) { saveTheKingdom(); }); }); }); }); }); });}); => // RuntimeException: NailNotFound
and all for the want of a horseshoe nail

beware callbacks



/\ ___ / \ ___ / \ __ / \ __ / / \ / \ _ / <()> \ _ / \ / \_/ \_/ \_/________\_/ \_/ \_/ __________________/__I___I___\________________ /_I___I___I__\ /I___I___I___I_\ /___I___I___I___I\ /__I___I___I___I___\ /_I___I___I___I___I__\ /I___I___I___I___I___I_\ /___I___I___I___I___I___I\ /__I___I___I___I___I___I___\ /_I___I___I___I___I___I___I__\
deceptively simple, monstrously complex




promises

if it happens, we'll let you know 


the promise

something might happen 

(the promise was fulfilled)


or it might not happen 
(the promise was rejected)



the interface

promise.then(onFulfilled, onRejected);

only one will be called
someone else decides which


async composition

promises beget more promises

loginRequest.then(function(user) {  return user.authenticate(); // => AuthenticatedUser}).then(function(authedUser) {
authedUser.useSystem(); });
 
fulfill promises by getting your work done


promises make async programming easier


un-invert the inversion of control
gain time independence
organize work into isolated units instead of nesting
code in isolation is easier to test
explicitly recognize non-determinism with logical branching (reject/fulfill)

...


async programming is still hard


promises are contageous
in order to compose promises you must return promises

promises are single use
can only be fulfilled or rejected once
cannot represent continuous streams of events, like user input

promises offer a powerful way to coordinate discrete events




reactive extensions

collection oriented async



Observerables & Subscriptions


observables are async event channels
discrete messages flow through the channels

subscriptions provide a way to tap into the stream
broadcast messaging provides any number of listeners to event sources




Rx provides stream collection operations
map to transform streams
filter to select particular messages
reduce to scan messages over time

each operation returns a new observable

turn async events emitters into observable workflows

rx : eventStreams :: promises : asyncEvents


reactive programming makes async powerful

keys = rx.observable("keypress");

enter = keys.filter(function(key) { return key == ENTER_CODE;});
enter.subscribe(doWork);

pretend event streams are just simple array-likes

messy async code is simple
just put a message on a stream


RxJava

by netflix
getStringsFromNetwork()
.skip(10) // who cares about the first ten messages .take(5) // i only want five messages .map({ s -> return(s + "_transformed"); }) .subscribe({ it -> println("onNext => " + it); });



more examples

  • bacon.js
  • storm
  • core.async
  • RxJs
  • LINQ




async programming is still hard

callbacks pyramids, actors, promises,
goroutines, reactive, 
race conditions, 
oh my...



no silver bullet


no solution is right for every problem
when you have a favorite hammer, everything starts looking like a nail

programming is a way to help us think about problems
only use patterns when they make things easier to understand


Principles of Reactive Programming


fundamentals of concurrency and async using reactive programming, taught in Scala by the author, Martin Odersky exploring Reactive Extensions, by the creator Erik Meijer.

Free course starts Nov 4th 2013 and runs for 7 weeks

happy coding
- tomans

async patterns

By Thomas Omans

async patterns

  • 1,547
Loading comments...

More from Thomas Omans