43
1 SEC-2015 Reactive programming every day

Reactive programming every day

Embed Size (px)

Citation preview

Page 1: Reactive programming every day

1SEC-2015

Reactive programmingevery day

Page 2: Reactive programming every day

2SEC-2015

Who am I?

Vadym Khondar

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

[email protected]

Page 3: Reactive programming every day

3SEC-2015

Goals

Why to useWhat is

How to usereactive programming

Page 4: Reactive programming every day

4SEC-2015

Why?

Page 5: Reactive programming every day

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

Page 6: Reactive programming every day

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

Page 7: Reactive programming every day

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

Page 8: Reactive programming every day

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/

Page 9: Reactive programming every day

9SEC-2015

Why those qualities?

Responsive

Resilient

Message-Driven

Elastic

Loose couplingLocation transparency

Responsive irrespectively to load Responsive irrespectively to failures

Asynchronous

Page 10: Reactive programming every day

10SEC-2015

So, if you still don’t

Page 11: Reactive programming every day

11SEC-2015

Tasks

We want our UI to not block.

We want our backend to not block.

* where it should not block

Page 12: Reactive programming every day

12SEC-2015

Reduce network latency influence

Page 13: Reactive programming every day

13SEC-2015

Events

Page 14: Reactive programming every day

14SEC-2015

Plain Old Observer pattern

Page 15: Reactive programming every day

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

Page 16: Reactive programming every day

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

Page 17: Reactive programming every day

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

Page 18: Reactive programming every day

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);

Page 19: Reactive programming every day

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);

Page 20: Reactive programming every day

20SEC-2015

But…

Pulling

Pushing

Page 21: Reactive programming every day

21SEC-2015

Page 22: Reactive programming every day

22SEC-2015

Definition

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

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

Page 23: Reactive programming every day

23SEC-2015

Reactive programming approach

Provide handy abstractions:

• Events and Event streams

• Behaviors

Page 24: Reactive programming every day

24SEC-2015

Event stream transformation

‘E’ pressed ‘a’ pressed

69 97

map()

•e -> e.charCode

Page 25: Reactive programming every day

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

Page 26: Reactive programming every day

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

Page 27: Reactive programming every day

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

Page 28: Reactive programming every day

28SEC-2015

Signal <> Event

Page 29: Reactive programming every day

29SEC-2015

Example: Arkanoid

Page 30: Reactive programming every day

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');

Page 31: Reactive programming every day

31SEC-2015

Futures and promises

Promise Future

Deferred PromiseJavaScript

Scala

CompletableFutureJava 8

Single write Multiple read

Page 32: Reactive programming every day

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() }}

Page 33: Reactive programming every day

33SEC-2015

Single item Many itemsPull/Synchronous

OptionalIterator/Iterable

Push/Asynchronous

FutureObserver/

Observable

Page 34: Reactive programming every day

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

Page 35: Reactive programming every day

35SEC-2015

Page 36: Reactive programming every day

36SEC-2015

Think abouthow data should flow

instead ofwhat you do to make it flow

Page 37: Reactive programming every day

37SEC-2015

Designing your API consider making it asynchronous

Page 38: Reactive programming every day

38SEC-2015

Get acquainted with functional programming

Page 39: Reactive programming every day

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

Page 40: Reactive programming every day

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

Page 42: Reactive programming every day

42SEC-2015

Page 43: Reactive programming every day

43SEC-2015

Code Presentation

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