Vert.x - Dessì

67
1 Massimiliano Dessì @desmax74

description

Slides from Massimiliano Dessì talk @ codemotion roma 2014

Transcript of Vert.x - Dessì

Page 1: Vert.x - Dessì

1

Massimiliano Dessì

@desmax74

Page 2: Vert.x - Dessì

2

ROME 11-12 april 2014 – Massimiliano Dessì

@desmax74

Massimiliano Dessì has more than 14 years of experience in programming. He’s a proud father of three. Manager of GDG Sardegna, Founder of S SpringFramework IT, co-founder of JugSardegna. Author of Spring 2.5 AOP. He works and lives in Cagliari, Italy.

Speaker

Page 3: Vert.x - Dessì

3

Vert.x

ROME 11-12 april 2014 – Massimiliano Dessì

Vert.x is a

lightweight (IoT)

polyglot

application development framework

for the JVM

enabling you

to build

high performance/reactive applications

Page 4: Vert.x - Dessì

4

ROME 11-12 april 2014 – Massimiliano Dessì

Page 5: Vert.x - Dessì

5

Software requirements nowadays

Highly Responsive

Real Time

Scalable

Resilient

Petabytes

ROME 11-12 april 2014 – Massimiliano Dessì

Page 6: Vert.x - Dessì

6

http://iamdany.com/Famous-Weapons

We need different weapons

(architectures)

New ProblemsNew ProblemsNew Problems

ROME 11-12 april 2014 – Massimiliano Dessì

Page 7: Vert.x - Dessì

7

Reactive

“readily responsive to a stimulus”

Component active and ready to respond to event

Event Driven

ROME 11-12 april 2014 – Massimiliano Dessì

Page 8: Vert.x - Dessì

8

React to events → Event Driven

React to failure → Resilient

React through a UI → Interactive

React to load → Scalable

Reactive

ROME 11-12 april 2014 – Massimiliano Dessì

Page 9: Vert.x - Dessì

9

Asyncronous and loosely coupled+

Non blocking=

lower latency and higher

throughput

React to event - Event driven

ROME 11-12 april 2014 – Massimiliano Dessì

Page 10: Vert.x - Dessì

10

Wear your Seatbelt

ROME 11-12 april 2014 – Massimiliano Dessì

Page 11: Vert.x - Dessì

11

Higher throughput

ROME 11-12 april 2014 – Massimiliano Dessì

http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-benchmarks/

http://www.techempower.com/benchmarks/

http://www.techempower.com/blog/2013/04/05/frameworks-round-2/

Page 12: Vert.x - Dessì

12

Old blocking model

ROME 11-12 april 2014 – Massimiliano Dessì

Page 13: Vert.x - Dessì

13

The “traditional” applications/containers

reserve

one thread

for each I/O resource,

this mean

one thread per connection,

this is a blocking architecture

because rest of incoming connections must await

Blocking apps

ROME 11-12 april 2014 – Massimiliano Dessì

Page 14: Vert.x - Dessì

14

Old blocking model

ROME 11-12 april 2014 – Massimiliano Dessì

Page 15: Vert.x - Dessì

15

“The C10k problem is the problem of optimising network

sockets to handle a large number of clients at the same

time”

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

ROME 11-12 april 2014 – Massimiliano Dessì

Page 16: Vert.x - Dessì

16

Concurrency solutions on jvm

ROME 11-12 april 2014 – Massimiliano Dessì

- No shared mutable state (all solutions derived from this) -

Functional approach [Scala, JDK8]

Actors [Akka]

Reactor/EventLoop [Vertx]

...

Page 17: Vert.x - Dessì

17

Reactor pattern

ROME 11-12 april 2014 – Massimiliano Dessì

Page 18: Vert.x - Dessì

18

Reactor pattern

ROME 11-12 april 2014 – Massimiliano Dessì

Page 19: Vert.x - Dessì

19

Event Loop

ROME 11-12 april 2014 – Massimiliano Dessì

The Reactor pattern

implementation in Vertx

is based on

Netty

EventLoop

Page 20: Vert.x - Dessì

20

http://500px.com/photo/40357406

Event Loop

ROME 11-12 april 2014 – Massimiliano Dessì

Page 21: Vert.x - Dessì

21

Non blocking – Netty approach

ROME 11-12 april 2014 – Massimiliano Dessì

Page 22: Vert.x - Dessì

22

Non blocking – Netty approach

ROME 11-12 april 2014 – Massimiliano Dessì

An eventLoop is powered by exactly on eThread

that never change.

The Events and task are executed in a FIFO order

Page 23: Vert.x - Dessì

23

Netty thread model internals

ROME 11-12 april 2014 – Massimiliano Dessì

Page 24: Vert.x - Dessì

24

EventLoop Internals

ROME 11-12 april 2014 – Massimiliano Dessì

Page 25: Vert.x - Dessì

25

EventLoop Vertx through Nettypublic class EventLoopContext extends DefaultContext {

….

public void execute(Runnable task) {

getEventLoop().execute(wrapTask(task));

}

public boolean isOnCorrectWorker(EventLoop worker) {

return getEventLoop() == worker;

}

}

ROME 11-12 april 2014 – Massimiliano Dessì

Page 26: Vert.x - Dessì

26

protected Runnable wrapTask(final Runnable task) {

return new Runnable() {

public void run() {

Thread currentThread = Thread.currentThread();

String threadName = currentThread.getName();

try {

vertx.setContext(DefaultContext.this);

task.run();

} catch (Throwable t) {

reportException(t);

} finally {

if (!threadName.equals(currentThread.getName())) {

currentThread.setName(threadName);

}

}

if (closed) {

unsetContext();

}

}

ROME 11-12 april 2014 – Massimiliano Dessì

Page 27: Vert.x - Dessì

27

EventLoop Vertx through Netty

The benefit of executing

the task in the event loop is

that you don’t need to worry

about any synchronization.

The runnable will get executed

in the same thread as all

other events that are related to the channel.

ROME 11-12 april 2014 – Massimiliano Dessì

Page 28: Vert.x - Dessì

28

When the data arrives from the outside or from inside,

the event loop thread wakes up,

executes any callback function registered for the specific event type,

and returns to its wait state until a new event occurs

Vertx

creates as many event loop threads as the number of CPU cores

Event Loops

ROME 11-12 april 2014 – Massimiliano Dessì

Page 29: Vert.x - Dessì

29

The unit of execution is a Verticle

which reacts to event messages,

and communicates sending event messages.

Decoupling communication

with event handlers and messages

enables location transparency

and

async composition (RxJava)

Event Loops

ROME 11-12 april 2014 – Massimiliano Dessì

Page 30: Vert.x - Dessì

30

Never block the Event Loop

Never block the Event Loop

Never block the Event Loop

If you need a blocking and long computation code

use a separate thread for this

Golden Rule

ROME 11-12 april 2014 – Massimiliano Dessì

Page 31: Vert.x - Dessì

31

Vertx provide an abstraction in which write code like a single-

thread, this abstraction is called Verticle.

In classic framework we have to write Controller or Service

Object, with Vertx all communications are async with events

through Verticles.

Direct calls does not exist in Vertx,

all calls are messages on Event Bus

Verticle

ROME 11-12 april 2014 – Massimiliano Dessì

Page 32: Vert.x - Dessì

32

Verticles packaging (Module)

ROME 11-12 april 2014 – Massimiliano Dessì

A module is a collection of verticles and other code and files

that is packaged as a unit,

and then referenced from other Vert.x modules or applications.

The module descriptor is a JSON file called mod.json

{ "main": "MyPersistor.java" //runnable "worker": true //worker verticle "preserve-cwd":true ...}

Page 33: Vert.x - Dessì

33

Event Bus distributed

Vertx

Vertx

Vertx

Ev

en

tb

us

Ev

en

tb

us

Ev

en

tl

oo

ps

Multicast

Browsers

ROME 11-12 april 2014 – Massimiliano Dessì

Location

transparency

Page 34: Vert.x - Dessì

34

public class MyVerticle extends Verticle {

@Override

public void start() {

// register handlers

}

@Override

public void start(Future<Void> startedResult) {

// register handlers

}

@Override

public void stop() {...}

}

Verticle

ROME 11-12 april 2014 – Massimiliano Dessì

Page 35: Vert.x - Dessì

35

Verticle

● Each Verticle instance is executed from only one thread

● Each Verticle instance assigned to thread/EventLoop

● Separate classloader for each Verticle

● Polyglot Verticles

● React to event with event handlers

ROME 11-12 april 2014 – Massimiliano Dessì

Page 36: Vert.x - Dessì

36

Polyglot Verticles

ROME 11-12 april 2014 – Massimiliano Dessì

Page 37: Vert.x - Dessì

37

Vertx provide Worker verticles

that run on a separate thread

to perform blocking operations

without block the Eventloop

Worker Verticle

ROME 11-12 april 2014 – Massimiliano Dessì

Page 38: Vert.x - Dessì

38

Message to object (roots)

Sending Messages to Objects

all Smalltalk processing is accomplished by sending messages to

objects. An initial problem solving approach in Smalltalk is to try to reuse

the existing objects and message

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

ROME 11-12 april 2014 – Massimiliano Dessì

Page 39: Vert.x - Dessì

39

Handlers

EventBus bus = vertx.eventBus();

Handler<Message> handler = new Handler<Message>() {

@Override

public void handle(Message message) {

//doSomething

}

}

bus.registerHandler("com.codemotion.firsthandler", handler);

ROME 11-12 april 2014 – Massimiliano Dessì

Page 40: Vert.x - Dessì

40

Pub Sub

EventBus bus = vertx.eventBus();

bus.publish(“com.codemotion.firsthandler”, “Hello world”);

publish mean broadcast, all subscribers

ROME 11-12 april 2014 – Massimiliano Dessì

Page 41: Vert.x - Dessì

41

P2P

EventBus bus = vertx.eventBus();

bus.send(“39.216667.Nord-9.116667.Est”, “Hello world”);

send mean point to point, only one subscriber, round robin

ROME 11-12 april 2014 – Massimiliano Dessì

Page 42: Vert.x - Dessì

42

Sender

bus.send("39.216667.Nord-9.116667.Est", "This is a message !", new Handler<Message<String>>() {

@Override

public void handle(Message<String> message) {

String received = message.body();

}

});

ROME 11-12 april 2014 – Massimiliano Dessì

Page 43: Vert.x - Dessì

43

Receiver

Handler<Message> handler = new Handler<Message<String>>() { @Override

public void handle(Message<String message) {

String received = message.body();

message.reply("This is a reply");

}

}

bus.registerHandler("39.216667.Nord-9.116667.Est", handler);

ROME 11-12 april 2014 – Massimiliano Dessì

Page 44: Vert.x - Dessì

44

Message from the UI

ROME 11-12 april 2014 – Massimiliano Dessì

<script src="http://cdn.sockjs.org/sockjs-0.3.4.min.js"></script><script src='vertxbus.js'></script>

<script>

var eb = new vertx.EventBus('http://localhost:8080/eventbus');

eb.onopen = function() {

eb.registerHandler('some-address', function(message) {

console.log('received a message: ' + JSON.stringify(message);

});

eb.send('some-address', {name: 'tim', age: 587});

}

</script>

Page 45: Vert.x - Dessì

45

Goodies

ROME 11-12 april 2014 – Massimiliano Dessì

● HTTP/HTTPS servers/clients

● WebSockets support

● SockJS support

● Timers

● Buffers

● Streams and Pumps

● Routing

● Async File I/O

● Shared Data

● Module Repo

(http://modulereg.vertx.io/)

● WebServer● SessionManager● Auth manager● Persistors (Mongo, JDBC)● Spring● RxJava● Many others● Compile on the fly

(deploy .java verticle)

Page 46: Vert.x - Dessì

46

eventBus.sendWithTimeout("test.address", "This is a message", 1000,

new Handler<AsyncResult<Message<String>>>() {

public void handle(AsyncResult<Message<String>> result) {

if (result.succeeded()) {

System.out.println("I received a reply " + message.body);

} else {

ReplyException ex = (ReplyException)result.cause();

System.err.println("Failure type: " + ex.failureType();

System.err.println("Failure code: " + ex.failureCode();

System.err.println("Failure message: " + ex.message();

// restart dead verticle ?

}

}

});

Notification of reply failure

ROME 11-12 april 2014 – Massimiliano Dessì

https://github.com/Netflix/RxJava/wiki

ROME 11-12 april 2014 – Massimiliano Dessì

Page 47: Vert.x - Dessì

47

long timerID = vertx.setPeriodic(1000, new

Handler<Long>() {

public void handle(Long timerID) {

log.info("And every second this is printed");

}

});

log.info("First this is printed");

Timers

ROME 11-12 april 2014 – Massimiliano Dessì

https://github.com/Netflix/RxJava/wiki

Page 48: Vert.x - Dessì

48

long timerID = vertx.setPeriodic(1000, new

Handler<Long>() {

public void handle(Long timerID) {

log.info("And every second this is printed");

}

});

log.info("First this is printed");

Timers

ROME 11-12 april 2014 – Massimiliano Dessì

https://github.com/Netflix/RxJava/wiki

Page 49: Vert.x - Dessì

49

Futures are Expensive to Compose

“Futures are straight-forward to use for a single level of

asynchronous execution but they start to add non-trivial

complexity when they're nested. “

RxJava

ROME 11-12 april 2014 – Massimiliano Dessì

https://github.com/Netflix/RxJava/wiki

Page 50: Vert.x - Dessì

50

RxJava

ROME 11-12 april 2014 – Massimiliano Dessì

Reactive

Functional reactive offers efficient execution and composition by

providing a collection of operators capable of filtering, selecting,

transforming, combining and composing Observable's.

https://github.com/Netflix/RxJava/wiki

Page 51: Vert.x - Dessì

51

RxJava

ROME 11-12 april 2014 – Massimiliano Dessì

def simpleComposition() {

customObservableNonBlocking()

.skip(10)// skip the first 10

.take(5)// take the next 5

.map({ stringValue -> return stringValue+ "transf"})

.subscribe({ println "onNext => " + it})

}

https://github.com/Netflix/RxJava/wiki

Page 52: Vert.x - Dessì

52

“The Observable data type can be thought of as a "push"

equivalent to Iterable which is "pull". With an Iterable, the

consumer pulls values from the producer and the thread blocks

until those values arrive.

By contrast with the Observable type, the producer pushes

values to the consumer whenever values are available. This

approach is more flexible, because values can arrive

synchronously or asynchronously.”

RxJava

ROME 11-12 april 2014 – Massimiliano Dessì

https://github.com/Netflix/RxJava/wiki

Page 53: Vert.x - Dessì

53

“The Observable type adds two missing semantics to the Gang

of Four's Observer pattern, which are available in the Iterable

type:

1) The ability for the producer to signal to the consumer that

there is no more data available.

2)The ability for the producer to signal to the consumer that an

error has occurred.”

RxJava

https://github.com/Netflix/RxJava/wiki

ROME 11-12 april 2014 – Massimiliano Dessì

Page 54: Vert.x - Dessì

54

RxJava a library (Java, Groovy, Scala, Clojure, JRuby)

for composing asynchronous and event-based programs by

using observable sequences .

It extends the observer pattern to support sequences of

data/events and adds operators that allow you to compose

sequences together declaratively while abstracting away

concerns about things like low-level threading, synchronization,

thread-safety, concurrent data structures, and non-blocking I/O.

RxJava

https://github.com/Netflix/RxJava/wiki

ROME 11-12 april 2014 – Massimiliano Dessì

Page 55: Vert.x - Dessì

55

RxJava

ROME 11-12 april 2014 – Massimiliano Dessì

def Observable<T> getData(int id) {

if(availableInMemory) {// sync

return Observable.create({ observer ->

observer.onNext(valueFromMemory);

observer.onCompleted();

})

} else { //Async

return Observable.create({ observer ->

executor.submit({

try {

T value = getValueFromRemoteService(id);

observer.onNext(value);

observer.onCompleted();

}catch(Exception e) {

observer.onError(e);

}

})

});

}}

No differenences from

the client perspective,

an Observable in both cases

http://netflix.github.io/RxJava/javadoc/rx/package-tree.html

Page 56: Vert.x - Dessì

56

mod-rxvertx

https://github.com/Netflix/RxJava/wiki

RxEventBus rxEventBus = new RxEventBus(vertx.eventBus());

rxEventBus.<String>registerHandler("foo").subscribe(new Action1<RxMessage<String>>() {

public void call(RxMessage<String> message) { message.reply("pong!");// Send a single reply }});

Observable<RxMessage<String>> obs = rxEventBus.send("foo", "ping!");

obs.subscribe( new Action1<RxMessage<String>>() { public void call(RxMessage<String> message) { // Handle response } }, new Action1<Throwable>() { public void call(Throwable err) { // Handle error } });

ROME 11-12 april 2014 – Massimiliano Dessì

Page 57: Vert.x - Dessì

57

Deploy module runtime

ROME 11-12 april 2014 – Massimiliano Dessì

// You can require API modules piecemealvar container = require('vertx/container');

// Or you can pull everything in at once// var vertx = require('vertx');// var container = vertx.container;

var config = { "web_root": ".", "port": 8080};

//downloaded form vertx repositorycontainer.deployModule("io.vertx~mod-web-server~2.0.0-final", config);

When a module is run with HA, if the Vert.x instance where it is running fails, it will be re-started automatically on another node of the cluster. We call this module fail-over.

To run a module with HA, you simply add the -ha switch when running it on the command line, for example:

Page 58: Vert.x - Dessì

58

Automatic failover

ROME 11-12 april 2014 – Massimiliano Dessì

When a module is run with HA, if the Vert.x instance where it is

running fails, it will be re-started automatically on another node of

the cluster. We call this module fail-over.

To run a module with HA, you simply add the -ha switch when

running it on the command line, for example:

vertx runmod com.acme~my-mod~2.1 -ha

org.vertx.java.platform.impl.HAManager

Page 59: Vert.x - Dessì

59

HTTP (Java)

ROME 11-12 april 2014 – Massimiliano Dessì

HttpServer server = vertx.createHttpServer();

server.requestHandler(new Handler< HttpServerRequest >() { public void handle(HttpServerRequest request) { request.response().write("Hello world").end(); }});

server.listen(8080, "localhost");

Page 60: Vert.x - Dessì

60

HTTP (JavaScript)

ROME 11-12 april 2014 – Massimiliano Dessì

var vertx = require('vertx');

var server = vertx.createHttpServer();

server.requestHandler(function(request) { request.response.write("Hello world").end();});

server.listen(8080, "localhost");

Page 61: Vert.x - Dessì

61

HTTP (Scala)

ROME 11-12 april 2014 – Massimiliano Dessì

vertx.createHttpServer.requestHandler {

req: HttpServerRequest => req.response.end("Hello World!")

}.listen(8080)

Page 62: Vert.x - Dessì

62

HTTP (Clojure)

ROME 11-12 april 2014 – Massimiliano Dessì

(ns demo.verticle (:require [vertx.http :as http] [vertx.stream :as stream])) (defn req-handler [req] (-> (http/server-response req) (stream/write "Hello world !") (http/end))) (-> (http/server) (http/on-request req-handler) (http/listen 8080))

Page 63: Vert.x - Dessì

63

HTTP (JRuby)

ROME 11-12 april 2014 – Massimiliano Dessì

require "vertx"

server = Vertx::HttpServer.new

server.request_handler do |request| request.response.write("Hello world").end;end

server.listen(8080, "localhost")

Page 64: Vert.x - Dessì

64

Vertx on RaspberryPipublic class HardwareVerticle extends Verticle {

public void start() {

final GpioController gpio = GpioFactory.getInstance();

System.out.println("GPIO LOADED");

final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_06, PinPullResistance.PULL_DOWN);

myButton.addListener(new GpioPinListenerDigital() {

@Override

public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event){

System.out.println(new Date() + "Button change");

vertx.eventBus().publish("buttonbus",String.valueOf(event.getState().getValue()));

}

});

}

}

http://szimano.org/how-to-use-vert-x-to-make-your-raspberrypi-talk-to-your-browser/

ROME 11-12 april 2014 – Massimiliano Dessì

Page 65: Vert.x - Dessì

65

● http://www.reactivemanifesto.org/

● http://vertx.io/

● http://netty.io/

● https://github.com/Netflix/RxJava

● http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf

● http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

● http://www.cs.wustl.edu/~schmidt/PDF/reactor-siemens.pdf

● http://www.cs.bgu.ac.il/~spl051/Personal_material/Practical_sessions/Ps_12/ps12.html

References

ROME 11-12 april 2014 – Massimiliano Dessì

Page 66: Vert.x - Dessì

66

References speaker

ROME 11-12 april 2014 – Massimiliano Dessì

http://www.slideshare.net/desmax74

https://twitter.com/desmax74

it.linkedin.com/in/desmax74

Page 67: Vert.x - Dessì

67

Thanks for your attention !

ROME 11-12 april 2014 – Massimiliano Dessì