reactive programming every day

Post on 10-Aug-2015

35 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1SEC-2015

Reactive programmingevery day

2SEC-2015

Who am I?

Vadym Khondar

Senior Software engineer 8 years experience 2.5 years with EPAMDevelopment team leadWeb, JavaScript, Java

vadym@khondar.name

3SEC-2015

Goals

Why to useWhat is

How to usereactive programming

4SEC-2015

Why?

5SEC-2015

Evolution of Internet

938 millions in June, 20043,035 millions in June, 2014

http://www.internetworldstats.com/emarketing.htm

1,440 millions in May, 2015

6SEC-2015

Evolution of expectations

• You see response to your actions quite quickly• You don’t notice if something breaks• You can collaborate• You have everything you need at the place you are

7SEC-2015

1995 1997 1999 2001 2003 2005 2007 2009 2011 2013 2015

Evolution of challenges

Tens of servers

Seconds of response time

Hours of offline maintenance

Gigabytes of data

Millisecond response times

100% uptime

Cloud

Mobile devices

Internet of Things

8SEC-2015

Definition of reactive system

Reactive Systems are:

• Message-driven (react to events)• Elastic (react to load)• Resilient (react to failures)• Responsive (react to users)

http://www.reactivemanifesto.org/

9SEC-2015

Why those qualities?

Responsive

Resilient

Message-Driven

Elastic

Loose couplingLocation transparency

Responsive irrespectively to load Responsive irrespectively to failures

Asynchronous

10SEC-2015

So, if you still don’t

11SEC-2015

Tasks

We want our UI to not block.

We want our backend to not block.

* where it should not block

12SEC-2015

Reduce network latency influence

13SEC-2015

Events

14SEC-2015

Plain Old Observer pattern

15SEC-2015

1. Encapsulation principle may be violated

2. Separation of concerns principle may be violated

3. Not easily composable

4. Inversion of control

Observer pattern problems

16SEC-2015

$(function() { var currentWord = '';

$('#textin').keypress(function(event) { var key = String.fromCharCode(event.keyCode || event.charCode);

if (!key.match(/[\w]/) && currentWord) { var link = 'https://twitter.com/hashtag/' + currentWord;

$('#textout').append($(' ')).append( $('<a/>').attr('href', link).text('#' + currentWord) );

currentWord = ''; } else if (key) { currentWord += key; } });});

Example: Hash tagger

State

Mixing logic with presentation

No easy way to compose with another handler of keypress

17SEC-2015

Callback hellpublic class ReportsEntryPoint { @Override public void onModuleLoad() { String documentIdString = Window.Location.getParameter("docId"); if (documentIdString != null && !documentIdString.isEmpty()) { try { final Long documentId = Long.parseLong(documentIdString); MainService.Util.getInstance().findReport(documentId, new AsyncCallback<ReportDto>() { // Getting Report information first @Override public void onSuccess(ReportDto result) { final ReportDto processedReport = result; MainService.Util.getInstance().getUserInfo(processedReport.getUserId(), processedReport.getCompanyId(), new AsyncCallback<UserCompanyDto>() { // Getting user information for future form initialization @Override public void onSuccess(UserCompanyDto result) { UserDataHolder.getInstance().setUserCompanyDto(result); MainService.Util.getInstance().getDProfile(processedReport.getCompanyId(), new AsyncCallback<DProfileDto>() { // Getting company profile for future form initialization @Override public void onSuccess(DProfileDto result) { UserDataHolder.getInstance().setDProfileDto(result); MainService.Util.getInstance().getPProfile(processedReport.getCompanyId(), new AsyncCallback<PProfileDto>() { // Getting company profile for future form initialization @Override public void onSuccess(PProfileDto result) { UserDataHolder.getInstance().setPProfileDto(result); MainService.Util.getInstance().getFormDto(processedReport, new AsyncCallback<FormDTO>() { // Getting report document form @Override public void onFailure(Throwable caught) { Window.alert("Can't get document: " + caught.getMessage()); ReportEditorEntryPoint.windowClose(); } @Override public void onSuccess(FormDTO result) { if (result == null) { Window.alert("Can't get document."); ReportEditorEntryPoint.windowClose(); return; }

// -- some code to process if finally everything is ok! } })

http://callbackhell.com

18SEC-2015

Goods

// handling single valueOptional<Double> amount = Optional.of(1.0);int roundedAmount = amount.orElse(2.0).intValue();

// handling multiple valuesStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).filter(i -> i % 2 == 0).skip(1).limit(2).forEachOrdered(System.out::println);

19SEC-2015

List<String> yellowFruits = new LinkedList<>();for (String fruit : fruits) { if (fruit.toLowerCase().contains("yellow")) { yellowFruits.add(fruit); }}

Collections.sort(yellowFruits);

for (String fruit : yellowFruits) { System.out.println(fruit);}

fruits.stream() .filter(f -> f.toLowerCase().contains("yellow")) .sorted() .forEach(System.out::println);

20SEC-2015

But…

Pulling

Pushing

21SEC-2015

22SEC-2015

Definition

Reactive programming is paradigm oriented around data flows and propagation of change.

http://en.wikipedia.org/wiki/Reactive_programming

23SEC-2015

Reactive programming approach

Provide handy abstractions:

• Events and Event streams

• Behaviors

24SEC-2015

Event stream transformation

‘E’ pressed ‘a’ pressed

69 97

map()

•e -> e.charCode

25SEC-2015

combine() – stream containing events from either combined streams

concat() – stream containing items of first stream and then of another stream

Stream transformation

map(Type1 => Type2) – stream of values from given function applied to each element in source streamfilter(Type => Boolean) – stream of values from source stream for which given function returns Truereduce((Type1, Type2) => Type1) (or scan(Fn, seed)) – stream of single value which is result of applying given function to element in source stream and result of previous call to given functionskip(num) – stream produced from source stream by skipping num elements

take(num) – stream produced from source stream by taking num first elements

Transforming

Combining

26SEC-2015

Example: Hash tagger reactive

No global state

Clear separation of concerns

Declarative description

$(function () { var keyStream = Rx.Observable.fromEvent($('#textin'), 'keypress') .map(function (event) { return String.fromCharCode(event.keyCode || event.charCode); }); var endOfWordStream = keyStream.filter(function (char) { return !String(char).match(/[\w]/); }); var wordStream = keyStream.buffer(endOfWordStream);

var uiUpdater = Rx.Observer.create(function (word) { word = word.join('').trim(); var link = 'https://twitter.com/hashtag/' + word;

$('#textout').append($(' ')).append( $('<a/>').attr('href', link).text('#' + word) ); });

wordStream.subscribe(uiUpdater);});

Composable API

27SEC-2015

Behavior (Signal)

Behaviors are used to express continuous dependency between values.They are often referred to as function from time domain to value domain.They are also called signals or properties.

Example: 90 - minute x 6 angle of minute

arrow on the clock

28SEC-2015

Signal <> Event

29SEC-2015

Example: Arkanoid

30SEC-2015

Example: Arkanoid – using property for mouse control

// some constantsvar canvasLeft = $('#gamecanvas').offset().left + window.screenX;var canvasRight = canvasLeft + $('#gamecanvas').width();var canvasMid = (canvasRight + canvasLeft) / 2;// define event stream for mouse movementvar mousePos = $('html') .asEventStream('mousemove') .map(function (event) { return {x: event.screenX, y: event.screenY}; });// define paddle position as a property in terms of mouse – stateless computationvar vausPos = mousePos.map(function (canvasLeft, canvasMid, canvasRight, coords) { return ((coords.x < canvasLeft || coords.x > (canvasRight - 40)) ? (coords.x < canvasMid ? canvasLeft : (canvasRight - 40)) : coords.x) - canvasLeft;}, canvasLeft, canvasMid, canvasRight).toProperty();// tie property to presentationvausPos.assign($('#vaus'), 'css', 'left');

31SEC-2015

Futures and promises

Promise Future

Deferred PromiseJavaScript

Scala

CompletableFutureJava 8

Single write Multiple read

32SEC-2015

Producer Consumer

import scala.concurrent.{ future, promise }import scala.concurrent.ExecutionContext.Implicits.globalval p = promise[T]val f = p.future

val producer = future { // async val r = produceSomething() p success r // completion of future scontinueDoingSomethingUnrelated()}

val consumer = future { // async startDoingSomething() f onSuccess { // what to do on completion case r => doSomethingWithResult() }}

33SEC-2015

Single item Many itemsPull/Synchronous

OptionalIterator/Iterable

Push/Asynchronous

FutureObserver/

Observable

34SEC-2015

Reactive programming

Benefits

• gives you a base for creating reactive systems

• gives you means of handling async in more elegant way

• stimulates you to write more concise code

Drawbacks

• might be harder do debug

35SEC-2015

36SEC-2015

Think abouthow data should flow

instead ofwhat you do to make it flow

37SEC-2015

Designing your API consider making it asynchronous

38SEC-2015

Get acquainted with functional programming

39SEC-2015

• Rx JS (http://reactivex.io/) – Observable on steroids• Bacon.js (https://baconjs.github.io/) – EventStreams and

Properties (behaviors)• Kefir.js (https://rpominov.github.io/kefir/) - inspired by

Bacon.js and RxJS with focus on high performance and low memory usage

Tools - Frontend

40SEC-2015

• Java 8 (hello to Streams, lambdas, CompletableFuture)• Scala (gives a good taste of functional paradigm while

letting you have old habits)• RxJava (https://github.com/ReactiveX/RxJava/)

Tools - Backend

42SEC-2015

43SEC-2015

Code Presentation

https://goo.gl/BlJSCy http://goo.gl/suJ2Xg

top related