Trayan Iliev
CEO of IPT – Intellectual
Products & Technologies
tiliev@iproduct.org
http://iproduct.org
BGOUG Conference
June 3-5 ‘16, Borovetz
High Performance
Reactive Programing
with Java 8
2
IPT – Intellectual Products &
Technologies: IT Education Evolved
Since 2003 we provide trainings and share skills &
knowledge in Java SE/ EE/ Web/ JS/ Angular / React:
Java EE/Web, JSF 2, Portlets, Portals: Liferay, GateIn
Reactive IoT with Reactor / RxJava / RxJS
Angular 2 + Ionic 2+ TypeScript web/mobile client MV*
frameworks
REST HATEOAS – Distributed Hypermedia APIs
Domain Driven Design, Reactive Microservices,
CQRS and Event Sourcing
Oracle® & Java™ are (registered) trademarks of Oracle and/or its affiliates. Liferay® is
registered trademark of Liferay, Inc. Other names may be trademarks of their respective owners.
3
High Performnce Reactive JAVA
 Reactive programming. Reactor & Proactor design
patterns. Reactive Streams (java.util.concurrent.Flow)
 High performance non-blocking asynchronous apps
on JVM using Reactor project & RxJava
 Disruptor (RingBuffer), Flux & Mono, Processors
 End-to-end reactive web applications and services:
Reactor IO (REST, WebSocket) + RxJS + Angular 2
 Demo - reactive hot event streams processing on
Raspberry Pi 2 (ARM v7) based robot IPTPI.
 RxJava (not Zen only :) coans for self assessment
4
The Internet of Things has the potential to change the
world, just as the Internet did. Maybe even more so.
 Nearly 50 petabytes of data are captured and created
by human beings
 People have limited time, attention and accuracy
 Capturing data about things in the real world in real time
 Track and count everything, reduce waste, loss & cost.
 Know when things need replacing, repairing or recalling
— Kevin Ashton, 'That 'Internet of Things' Thing', RFID Journal,
2009
Internet of Things (IoT)
5
Robots: The Most Intelligent Things
CC BY 2.0, Source:
https://www.flickr.com/photos/wilgengebroed/8249565455/
Radar, GPS, lidar for navigation and obstacle
avoidance ( 2007 DARPA Urban Challenge )
6
Tracking Complexity
We need tools to cope with all that complexity inherent in
robotics and IoT domains.
Simple solutions are needed – cope with problems through
divide and concur on different levels of abstraction:
Domain Driven Design (DDD) – back to basics:
domain objects, data and logic.
Described by Eric Evans in his book:
Domain Driven Design: Tackling Complexity in the Heart of
Software, 2004
7
Be Reactive: What It Really Means?
My Favourite Definition of
Reactive Streams :)
https://youtu.be/qybUFnY7Y8w
8
Imperative and Reactive
We live in a Connected Universe
... there is hypothesis that all
the things in the Universe are
intimately connected, and you
can not change a bit without
changing all.
Action – Reaction principle is
the essence of how Universe
behaves.
9
Imperative and Reactive
 Reactive Programming: using static or dynamic data
flows and propagation of change
Example: a := b + c
 Functional Programming: evaluation of mathematical
functions,
− Avoids changing-state and mutable data, declarative
programming
− Side effects free => much easier to understand and
predict the program behavior.
Example: books.stream().filter(book -> book.getYear() > 2010)
.forEach( System.out::println )
10
Functional Reactive (FRP)
According to Connal Elliot's (ground-breaking paper @
Conference on Functional Programming, 1997), FRP is:
(a) Denotative
(b) Temporally continuous
11
Reactive Manifesto
[http://www.reactivemanifesto.org]
12
Reactive Programming
 Microsoft®
opens source polyglot project ReactiveX
(Reactive Extensions) [http://reactivex.io]:
Rx = Observables + LINQ + Schedulers :)
Java: RxJava, JavaScript: RxJS, C#: Rx.NET, Scala: RxScala,
Clojure: RxClojure, C++: RxCpp, Ruby: Rx.rb, Python: RxPY,
Groovy: RxGroovy, JRuby: RxJRuby, Kotlin: RxKotlin ...
 Reactive Streams Specification
[http://www.reactive-streams.org/] used by
 (Spring) Project Reactor
[http://projectreactor.io/]
13
Reactive Streams Spec.
 Reactive Streams – provides standard for
asynchronous stream processing with non-blocking
back pressure.
 Minimal set of interfaces, methods and protocols for
asynchronous data streams
 April 30, 2015: has been released version 1.0.0 of
Reactive Streams for the JVM (Java API,
Specification, TCK and implementation examples)
 Java 9: java.util.concurrent.Flow
14
Reactive Streams Spec.
 Publisher – provider of potentially unbounded number
of sequenced elements, according to Subscriber(s)
demand.
Publisher.subscribe(Subscriber) => onSubscribe onNext*
(onError | onComplete)?
 Subscriber – calls Subscription.request(long) to
receive notifications
 Subscription – one-to-one Subscriber ↔ Publisher,
request data and cancel demand (allow cleanup).
 Processor = Subscriber + Publisher
15
FRP = Async Data Streams
 FRP is asynchronous data-flow programming using the
building blocks of functional programming (e.g. map,
reduce, filter) and explicitly modeling time
 Used for GUIs, robotics, and music. Example (RxJava):
Observable.from(
new String[]{"Reactive", "Extensions", "Java"})
.take(2).map(s -> s + " : on " + new Date())
.subscribe(s -> System.out.println(s));
Result:
Reactive : on Wed Jun 17 21:54:02 GMT+02:00 2015
Extensions : on Wed Jun 17 21:54:02 GMT+02:00 2015
16
 Performance is about 2 things (Martin Thompson –
http://www.infoq.com/articles/low-latency-vp ):
– Throughput – units per second, and
– Latency – response time
 Real-time – time constraint from input to response
regardless of system load.
 Hard real-time system if this constraint is not honored then
a total system failure can occur.
 Soft real-time system – low latency response with little
deviation in response time
 100 nano-seconds to 100 milli-seconds. [Peter Lawrey]
What About High Performance?
17
 Mechanical Sympathy – hardware (CPU, cache, memory,
IO, Network), operating system, language implementation
platform (e.g. JVM), and application level code are working
in harmony to minimize the time needed for event (request,
message) processing => 10% / 90% principle
 Throughput vs. latency – bus vs. car traveling
 Throughput ~ System Capacity / Latency
 Achieving low latency may mean additional work done
by system => lowered System Capacity and Throughput
 Horizontal scalability is valuable for high throughput. For
low latency, you need simplicity – critical path.
Throughput vs. Latency
18
 JVMs are often faster than custom C++ code because of the
holistic optimizations that they can apply across an application
[Andy Piper].
 Developers can take advantage of hardware guarantees through
a detailed understanding of:
– Java Memory Model & mapping to underlying hardware
– low latency software system hardware (CPU, cache, memory,
IO, Network)
– avoiding lock-contention and garbage collection
– Compre-And-Swap – CAS (java.util.concurrent.atomic)
– lock-free, wait-free techniques – using standard libraries (e.g.
the LMAX Disruptor)
High Performance Java
19
CPU Cache – False Sharing
Core 2 Core NCore 1 ...
Registers
Execution Units
L1 Cache A | | B |
L2 Cache A | | B |
L3 Cache A | | B |
DRAM Memory
A | | B |
Registers
Execution Units
L1 Cache A | | B |
L2 Cache A | | B |
20
 Low garbage by reusing existing objects + infrequent GC
when application not busy – can improve app 2 - 5x
 JVM generational GC startegy – ideal for objects living very
shortly (garbage collected next minor sweep) or be immortal
 Non-blocking, lockless coding or CAS
 Critical data structures – direct memory access using
DirectByteBuffers or Unsafe => predictable memory layout
and cache misses avoidance
 Busy waiting – giving the CPU to OS kernel slows program
2-5x => avoid context switches
 Amortize the effect of expensive IO - blocking
Low Latency: Things to Remember
21
 Parallel tasks can increase your throughput by increasing
system capacity – it is GOOD!
 But comes together with concurrent access to shared
resources => you have to provide mutual exclusion (MutEx)
by parallel threads when changing the resources' state (read
only access can be shared by multiple threads)
 Mutual exclusion can be achieved in several ways:
– synchronized – hardwired in HotSpot JVM, optimized in J^6
– ReentrantLock, ReadWriteLock, StampedLock →
java.util.concurrent.locks.*
– Optimistic Locking → tryLock(), CAS
Parallelism & Concurrency
22
Simple problem: incrementing a long value 500 000 000 times.
9 implementations:
‒ SynchronousCounter – while (counter++ < 500000000){}
‒ SingleThreadSynchronizedCounter – 1T using synchronized
‒ TwoThreadsSynchronizedCounter – 2T using synchronized
‒ SingleThreadCASCounter – 1T using AtomicLong
‒ TwoThreadsCASCounter – 2T using AtomicLong
‒ TwoThreadsCASCounterLongAdder – 1T using LongAdder
‒ SingleThreadVolatileCounter – 1T, memory barrier (volatile)
‒ TwoThreadsVolatileCounter – 2T, memory barrier (volatile)
Comparing Concurrent Impl.
23
Test results (on my laptop - quad core Intel i7@2.2GHz):
− SynchronousCounter – 190ms
− SingleThreadSynchronizedCounter – 15000 ms
− TwoThreadsSynchronizedCounter – 21000 ms
− SingleThreadCASCounter – 4100 ms
− TwoThreadsCASCounter – 12000 ms
− TwoThreadsCASCounterLongAdder – 12800 ms
− SingleThreadVolatileCounter – 4100 ms
− TwoThreadsVolatileCounter – 20000 ms
Comparing Concurrent Impl.
24
For more complete micro-benchmarking of
different Mutex implementations see:
http://blog.takipi.com/java-8-stampedlocks-vs-
readwritelocks-and-synchronized/
http://www.slideshare.net/haimyadid/java-8-
stamped-lock
Comparing Concurrent Impl.
25
 Non-blocking (synchronous) implementation is 2 orders of
magnitude better then synchronized
 We should try to avoid blocking and especially contended
blocking if want to achieve low latency
 If blocking is a must we have to prefer CAS and optimistic
concurrency over blocking (but have in mind it always
depends on concurrent problem at hand and how much
contention do we experience – test early, test often,
microbenchmarks are unreliable and highly platform dependent
– test real application with typical load patterns)
 The real question is: HOW is is possible to build concurrency
without blocking?
Mutex Comparison => Conclusions
26
 Message Driven – asynchronous message-passing allows
to establish a boundary between components that ensures
loose coupling, isolation, location transparency, and
provides the means to delegate errors as messages
[Reactive Manifesto].
 The main idea is to separate concurrent producer and
consumer workers by using message queues.
 Message queues can be unbounded or bounded (limited
max number of messages)
 Unbounded message queues can present memory
allocation problem in case the producers outrun the
consumers for a long period → OutOfMemoryError
Scalable, Massively Concurrent
27
 Queues typically use either linked-lists or arrays for the
underlying storage of elements. Linked lists are not
„mechanically sympathetic” – there is no predictable
caching “stride” (should be less than 2048 bytes in each
direction).
 Bounded queues often experience write contention on
head, tail, and size variables. Even if head and tail
separated using CAS, they usually are in the same cache-
line.
 Queues produce much garbage.
 Typical queues conflate a number of different concerns –
producer and consumer synchronization and data storage
Queues Disadvantages
[http://lmax-exchange.github.com/disruptor/files/Disruptor-1.0.pdf]
28
 LMAX Disruptor design pattern separates different
concerns in a “mechanically sympathetic” way:
- Storage of items being exchanged
- Producer coordination – claiming the next sequence
- Consumers coordination – notified new item is available
 Single Writer principle is employed when writing data in
the Ring Buffer from single producer thread only (no
contention),
 When multiple producers → CAS
 Memory pre-allocated – predictable stride, no garbage
LMAX Disruptor (RingBuffer)
[http://lmax-exchange.github.com/disruptor/files/Disruptor-1.0.pdf]
29
LMAX Disruptor (RingBuffer) High Performance
[http://lmax-exchange.github.com/disruptor/files/Disruptor-
1.0.pdf]
Source: LMAX Disruptor github wiki - https://raw.githubusercontent.com/wiki/LMAX-
Exchange/disruptor/images/Models.png
LMAX-Exchange Disruptor License @ GitHub: Apache License Version 2.0, January 2004 -
http://www.apache.org/licenses/
30
LMAX Disruptor (RingBuffer) High Performance
[http://lmax-exchange.github.com/disruptor/files/Disruptor-
1.0.pdf]
Source: LMAX Disruptor @ GitHub - https://github.com/LMAX-
Exchange/disruptor/blob/master/docs/Disruptor.docx
LMAX-Exchange Disruptor License @ GitHub: Apache License Version 2.0, January 2004 -
http://www.apache.org/licenses/
31
Project Reactor
 Reactor project allows building high-performance (low
latency high throughput) non-blocking asynchronous
applications on JVM.
 Reactor is designed to be extraordinarily fast and can
sustain throughput rates on order of 10's of millions of
operations per second.
 Reactor has powerful API for declaring data
transformations and functional composition.
 Makes use of the concept of Mechanical Sympathy
built on top of Disruptor / RingBuffer.
32
Project Reactor
 Pre-allocation at startup-time
 Message-passing structures are bounded
 Using Reactive and Event-Driven Architecture patterns
=> non-blocking end-to-end flows, replies
 Implement Reactive Streams Specification – efficient
bounded structures requesting no more than capacity
 Applies above features to IPC and provides non-
blocking IO drivers that are flow-control aware
 Expose a Functional API – organize their code in a
side-effect free way, which helps you determine you are
thread-safe and fault-tolerant
33
Reactor Projects
https://github.com/reactor/reactor, Apache Software License 2.0
34
Reactor Flux
https://github.com/reactor/reactor-core, Apache Software License 2.0
35
Reactor Mono
https://github.com/reactor/reactor-core, Apache Software License 2.0
36
Example: Flux.combineLatest()
https://projectreactor.io/core/docs/api/, Apache Software License 2.0
37
Reactor: Hello World
public class ReactorHelloWorld {
public static void main(String... args) throws
InterruptedException {
Broadcaster<String> sink = Broadcaster.create();
SchedulerGroup sched = SchedulerGroup.async();
sink.dispatchOn(sched)
.map(String::toUpperCase)
.filter(s -> s.startsWith("HELLO"))
.consume(s -> System.out.printf("s=%s%n", s));
sink.onNext("Hello World!");
sink.onNext("Goodbye World!");
Thread.sleep(500);
} }
38
Reactor Bus: IPTPI Java Robot
39
Meet IPTPI :)
4040
Ups...
41
IPTPI: RPi2 + Ardunio Robot
 Raspberry Pi 2 (quad-core ARMv7
@ 900MHz) + Arduino Leonardo
cloneA-Star 32U4 Micro
 Optical encoders (custom), IR
optical array, 3D accelerometers,
gyros, and compass MinIMU-9 v2
 IPTPI is programmed in Java
using Pi4J, Reactor, RxJava, Akka
 More information about IPTPI:
http://robolearn.org/iptpi-robot/
42
IPTPI: RPi2 + Ardunio Robot
3D accelerometers, gyros,
and compass MinIMU-9 v2
Pololu DRV8835
Dual Motor Driver
for Raspberry Pi
Arduino Leonardo clone
A-Star 32U4 Micro
USB Stereo
Speakers - 5V
LiPo Powebank
15000 mAh
43
IPTPI: RPi2 + Ardunio Robot
Raspberry Pi 2 (quad-core
ARMv7 @ 900MHz)
IR Optical Sensor QRD1114
Array (Line Following)
Adafruit 2.8" PiTFT -
Capacitive Touch Screen
4444
45
LeJaRo: Lego®
Java Robot
 Modular – 3 motors (with encoders) – one driving each
track, and third for robot clamp.
 Three sensors: touch sensor (obstacle avoidance), light
color sensor (follow line), IR sensor (remote).
 LeJaRo is programmed in Java using LeJOS library.
 More information about LeJaRo:
http://robolearn.org/lejaro/
 Programming examples available @GitHub:
https://github.com/iproduct/course-social-robotics/tre
e/master/motors_demo
LEGO® is a registered trademark of LEGO® Group. Programs of IPT are not
affiliated, sponsored or endorsed by LEGO® Education or LEGO® Group.
46
Tale of Simplicity: DDD
46
47
Let's See Some Real Code 
Reactive Websocket Demo available @GitHub:
https://github.com/iproduct/ipt-angular2-
reactive-websocket-demo
Reactive Robotics Demo available @GitHub:
https://github.com/iproduct/jprime-demo
48
IPTPI Reactive Streams
Encoder
Readings
ArduinoData
Fluxion
Arduino
SerialData
Position
Fluxion
Robot
Positions
Command
Movement
Subscriber
RobotWSService
(using Reactor)
Angular 2 /
TypeScript
MovementCommands
49
IPTPI: IPTPIDemo I
public class IPTPIVDemo {
...
public IPTPIDemo() {
//receive Arduino data readings
arduino = ArduinoDataFactory.createArduinoDataFluxion();
//calculate robot positions
positionsPub =PositionFactory.createPositionFluxion(arduino);
presentationViews.add(
PositionFactory.createPositionPanel(positionsPub));
//wire robot main controller with services
moveSub = MovementFactory
.createCommandMovementSubscriber(positionsPub);
controller = new RobotController(
Subscribers.consumer(this::tearDown),moveSub);
50
IPTPI: IPTPIDemo II
//create view with controller and delegate material views
//from query services
view = new RobotView("IPTPI Reactive Robotics Demo",
controller, presentationViews);
//expose as WS service
movementSub2 = MovementFactory
.createCommandMovementSubscriber(positionsPub);
positionsService =
new RobotWSService(positionsPub, movementSub2);
}
public static void main(String[] args) {
IPTPIVoxxedDemo demo = new IPTPIVoxxedDemo();
}
51
IPTPI: ArduinoDataFluxion I
fluxion = Broadcaster.create();
emitter = fluxion.startEmitter();
final Serial serial = SerialFactory.createInstance();
serial.addListener(new SerialDataEventListener() {
private ByteBuffer buffer = ByteBuffer.allocate(1024);
@Override
public void dataReceived(SerialDataEvent event) {
try {
ByteBuffer newBuffer = event.getByteBuffer();
buffer.put(newBuffer);
buffer.flip();
...
buffer.get();
long timestamp = buffer.getInt(); //get timestamp
int encoderL = -buffer.getInt(); //motors mirrored
int encoderR = buffer.getInt();
52
IPTPI: ArduinoDataFluxion II
EncoderReadings readings =
new EncoderReadings(encoderR, encoderL, timestamp);
emitter.submit(readings);
...
buffer.compact();
} catch (Exception e) {
e.printStackTrace();
}
}
});
try {
serial.open(PORT, 38400);
} catch(SerialPortException | IOException ex) {
System.out.println(“SERIAL SETUP FAILED:"+ex.getMessage());
}
53
IPTPI: PositionFluxion I
Redux
Pattern!
54
CommandMovementSubscriber I
public class CommandMovementSubscriber extends
ConsumerSubscriber<Command<Movement>> {
private PositionFluxion positions;
public CommandMovementSubscriber(PositionFluxion positions){
this.positions = positions;
Gpio.wiringPiSetupGpio(); // initialize wiringPi library
Gpio.pinMode(5, Gpio.OUTPUT); // Motor direction pins
Gpio.pinMode(6, Gpio.OUTPUT);
Gpio.pinMode(12, Gpio.PWM_OUTPUT); // Motor speed pins
Gpio.pinMode(13, Gpio.PWM_OUTPUT);
Gpio.pwmSetMode(Gpio.PWM_MODE_MS);
Gpio.pwmSetRange(MAX_SPEED);
Gpio.pwmSetClock(CLOCK_DIVISOR);
}
@Override
public void doNext(Command<Movement> command) { ... }
}
55
CommandMovementSubscriber II
private void runMotors(MotorsCommand mc) {
//setting motor directions
Gpio.digitalWrite(5, mc.getDirR() > 0 ? 1 : 0);
Gpio.digitalWrite(6, mc.getDirL() > 0 ? 1 : 0);
//setting speed
if(mc.getVelocityR()>=0 && mc.getVelocityR() <=MAX_SPEED)
Gpio.pwmWrite(12, mc.getVelocityR()); // set speed
if(mc.getVelocityL()>=0 && mc.getVelocityL() <=MAX_SPEED)
Gpio.pwmWrite(13, mc.getVelocityL());
}
}
56
Reactor IO – NetStreams API
http://projectreactor.io/io/docs/reference/, Apache License 2.0
57
IPTPI: RobotWSService I
private void setupServer() throws InterruptedException {
httpServer = NetStreams.<Buffer, Buffer>httpServer(
HttpServerSpec<Buffer,Buffer> serverSpec ->
serverSpec.listen("172.22.0.68", 80)
);
httpServer.get("/", getStaticResourceHandler());
httpServer.get("/index.html", getStaticResourceHandler());
httpServer.get("/app/**", getStaticResourceHandler());
...
httpServer.ws("/ws", getWsHandler());
httpServer.start().subscribe(
Subscribers.consumer(System.out::println));
}
58
IPTPI: RobotWSService II
private ReactorHttpHandler<Buffer, Buffer> getWsHandler() {
return channel -> {
System.out.println("Connected a websocket client: " +
channel.remoteAddress());
channel.map(Buffer::asString).consume(
json -> {
System.out.printf(“WS Message: %s%n“, json);
Movement movement = gson.fromJson(json, Movement.class);
movementCommands.onNext(new Command<>("move", movement));
});
return positions.flatMap(position ->
channel.writeWith(
Flux.just(Buffer.wrap(gson.toJson(position)))
));
};
}
59
Takeaways: Why Go Reactive?
Benefits using Reactive Programming + DDD:
 DDD helps to manage complexity in IoT and Robotics -
many subsystems = sub-domains
 Reactive Streams (Fluxes, Monos) = uni-directional data
flows, CQRS, event sourcing, microservices
 Reactive Streams can be non-blocking and highly
efficient, or can utilize blocking if needed
 Naturally implement state management patterns like
Redux, allow time travel, replay and data analytics
 Clear, declarative data transforms that scale (Map-
Reduce, BigData, PaaS)
60
Takeaways: Why Maybe Not?
Cons using Reactive Programming + DDD:
 DDD requires additional efforts to clearly separate
different (sub) domains – DSL translators, factories...
 Reactive Streams utilize functional composition and
require entirely different mindset then imperative – feels
like learning foreign language
 Pure functions and Redux provide much benefits,
but there's always temptation to “do it the old way” :)
 Tool support for functional programming in Java is still
not perfect (in Eclipse at least :)
61
Resources: RxMarbles & Rx Coans
RxMarbles:
http://rxmarbles.com/
RxJava Koans – Let's try to solve them at:
https://github.com/mutexkid/rxjava-koans
RxJS Koans – for those who prefer JavaScript :)
https://github.com/Reactive-Extensions/RxJSKoans
62
Interested in Reactive?
 IPT Reactive Java and Angular 2 + Typescript
courses: http://iproduct.org
 More information about robots @RoboLearn:
http://robolearn.org/
 TuxCon – 9-10 July, Plovdiv:
http://tuxcon.mobi/#schedule
63
Tale of Simplicity: DDD
63
http://robolearn.org/
64
Thank’s for Your Attention!
Trayan Iliev
CEO of IPT – Intellectual Products
& Technologies
http://iproduct.org/
http://robolearn.org/
https://github.com/iproduct
https://twitter.com/trayaniliev
https://www.facebook.com/IPT.EACAD
https://plus.google.com/+IproductOrg

IPT High Performance Reactive Java BGOUG 2016

  • 1.
    Trayan Iliev CEO ofIPT – Intellectual Products & Technologies [email protected] http://iproduct.org BGOUG Conference June 3-5 ‘16, Borovetz High Performance Reactive Programing with Java 8
  • 2.
    2 IPT – IntellectualProducts & Technologies: IT Education Evolved Since 2003 we provide trainings and share skills & knowledge in Java SE/ EE/ Web/ JS/ Angular / React: Java EE/Web, JSF 2, Portlets, Portals: Liferay, GateIn Reactive IoT with Reactor / RxJava / RxJS Angular 2 + Ionic 2+ TypeScript web/mobile client MV* frameworks REST HATEOAS – Distributed Hypermedia APIs Domain Driven Design, Reactive Microservices, CQRS and Event Sourcing Oracle® & Java™ are (registered) trademarks of Oracle and/or its affiliates. Liferay® is registered trademark of Liferay, Inc. Other names may be trademarks of their respective owners.
  • 3.
    3 High Performnce ReactiveJAVA  Reactive programming. Reactor & Proactor design patterns. Reactive Streams (java.util.concurrent.Flow)  High performance non-blocking asynchronous apps on JVM using Reactor project & RxJava  Disruptor (RingBuffer), Flux & Mono, Processors  End-to-end reactive web applications and services: Reactor IO (REST, WebSocket) + RxJS + Angular 2  Demo - reactive hot event streams processing on Raspberry Pi 2 (ARM v7) based robot IPTPI.  RxJava (not Zen only :) coans for self assessment
  • 4.
    4 The Internet ofThings has the potential to change the world, just as the Internet did. Maybe even more so.  Nearly 50 petabytes of data are captured and created by human beings  People have limited time, attention and accuracy  Capturing data about things in the real world in real time  Track and count everything, reduce waste, loss & cost.  Know when things need replacing, repairing or recalling — Kevin Ashton, 'That 'Internet of Things' Thing', RFID Journal, 2009 Internet of Things (IoT)
  • 5.
    5 Robots: The MostIntelligent Things CC BY 2.0, Source: https://www.flickr.com/photos/wilgengebroed/8249565455/ Radar, GPS, lidar for navigation and obstacle avoidance ( 2007 DARPA Urban Challenge )
  • 6.
    6 Tracking Complexity We needtools to cope with all that complexity inherent in robotics and IoT domains. Simple solutions are needed – cope with problems through divide and concur on different levels of abstraction: Domain Driven Design (DDD) – back to basics: domain objects, data and logic. Described by Eric Evans in his book: Domain Driven Design: Tackling Complexity in the Heart of Software, 2004
  • 7.
    7 Be Reactive: WhatIt Really Means? My Favourite Definition of Reactive Streams :) https://youtu.be/qybUFnY7Y8w
  • 8.
    8 Imperative and Reactive Welive in a Connected Universe ... there is hypothesis that all the things in the Universe are intimately connected, and you can not change a bit without changing all. Action – Reaction principle is the essence of how Universe behaves.
  • 9.
    9 Imperative and Reactive Reactive Programming: using static or dynamic data flows and propagation of change Example: a := b + c  Functional Programming: evaluation of mathematical functions, − Avoids changing-state and mutable data, declarative programming − Side effects free => much easier to understand and predict the program behavior. Example: books.stream().filter(book -> book.getYear() > 2010) .forEach( System.out::println )
  • 10.
    10 Functional Reactive (FRP) Accordingto Connal Elliot's (ground-breaking paper @ Conference on Functional Programming, 1997), FRP is: (a) Denotative (b) Temporally continuous
  • 11.
  • 12.
    12 Reactive Programming  Microsoft® openssource polyglot project ReactiveX (Reactive Extensions) [http://reactivex.io]: Rx = Observables + LINQ + Schedulers :) Java: RxJava, JavaScript: RxJS, C#: Rx.NET, Scala: RxScala, Clojure: RxClojure, C++: RxCpp, Ruby: Rx.rb, Python: RxPY, Groovy: RxGroovy, JRuby: RxJRuby, Kotlin: RxKotlin ...  Reactive Streams Specification [http://www.reactive-streams.org/] used by  (Spring) Project Reactor [http://projectreactor.io/]
  • 13.
    13 Reactive Streams Spec. Reactive Streams – provides standard for asynchronous stream processing with non-blocking back pressure.  Minimal set of interfaces, methods and protocols for asynchronous data streams  April 30, 2015: has been released version 1.0.0 of Reactive Streams for the JVM (Java API, Specification, TCK and implementation examples)  Java 9: java.util.concurrent.Flow
  • 14.
    14 Reactive Streams Spec. Publisher – provider of potentially unbounded number of sequenced elements, according to Subscriber(s) demand. Publisher.subscribe(Subscriber) => onSubscribe onNext* (onError | onComplete)?  Subscriber – calls Subscription.request(long) to receive notifications  Subscription – one-to-one Subscriber ↔ Publisher, request data and cancel demand (allow cleanup).  Processor = Subscriber + Publisher
  • 15.
    15 FRP = AsyncData Streams  FRP is asynchronous data-flow programming using the building blocks of functional programming (e.g. map, reduce, filter) and explicitly modeling time  Used for GUIs, robotics, and music. Example (RxJava): Observable.from( new String[]{"Reactive", "Extensions", "Java"}) .take(2).map(s -> s + " : on " + new Date()) .subscribe(s -> System.out.println(s)); Result: Reactive : on Wed Jun 17 21:54:02 GMT+02:00 2015 Extensions : on Wed Jun 17 21:54:02 GMT+02:00 2015
  • 16.
    16  Performance isabout 2 things (Martin Thompson – http://www.infoq.com/articles/low-latency-vp ): – Throughput – units per second, and – Latency – response time  Real-time – time constraint from input to response regardless of system load.  Hard real-time system if this constraint is not honored then a total system failure can occur.  Soft real-time system – low latency response with little deviation in response time  100 nano-seconds to 100 milli-seconds. [Peter Lawrey] What About High Performance?
  • 17.
    17  Mechanical Sympathy– hardware (CPU, cache, memory, IO, Network), operating system, language implementation platform (e.g. JVM), and application level code are working in harmony to minimize the time needed for event (request, message) processing => 10% / 90% principle  Throughput vs. latency – bus vs. car traveling  Throughput ~ System Capacity / Latency  Achieving low latency may mean additional work done by system => lowered System Capacity and Throughput  Horizontal scalability is valuable for high throughput. For low latency, you need simplicity – critical path. Throughput vs. Latency
  • 18.
    18  JVMs areoften faster than custom C++ code because of the holistic optimizations that they can apply across an application [Andy Piper].  Developers can take advantage of hardware guarantees through a detailed understanding of: – Java Memory Model & mapping to underlying hardware – low latency software system hardware (CPU, cache, memory, IO, Network) – avoiding lock-contention and garbage collection – Compre-And-Swap – CAS (java.util.concurrent.atomic) – lock-free, wait-free techniques – using standard libraries (e.g. the LMAX Disruptor) High Performance Java
  • 19.
    19 CPU Cache –False Sharing Core 2 Core NCore 1 ... Registers Execution Units L1 Cache A | | B | L2 Cache A | | B | L3 Cache A | | B | DRAM Memory A | | B | Registers Execution Units L1 Cache A | | B | L2 Cache A | | B |
  • 20.
    20  Low garbageby reusing existing objects + infrequent GC when application not busy – can improve app 2 - 5x  JVM generational GC startegy – ideal for objects living very shortly (garbage collected next minor sweep) or be immortal  Non-blocking, lockless coding or CAS  Critical data structures – direct memory access using DirectByteBuffers or Unsafe => predictable memory layout and cache misses avoidance  Busy waiting – giving the CPU to OS kernel slows program 2-5x => avoid context switches  Amortize the effect of expensive IO - blocking Low Latency: Things to Remember
  • 21.
    21  Parallel taskscan increase your throughput by increasing system capacity – it is GOOD!  But comes together with concurrent access to shared resources => you have to provide mutual exclusion (MutEx) by parallel threads when changing the resources' state (read only access can be shared by multiple threads)  Mutual exclusion can be achieved in several ways: – synchronized – hardwired in HotSpot JVM, optimized in J^6 – ReentrantLock, ReadWriteLock, StampedLock → java.util.concurrent.locks.* – Optimistic Locking → tryLock(), CAS Parallelism & Concurrency
  • 22.
    22 Simple problem: incrementinga long value 500 000 000 times. 9 implementations: ‒ SynchronousCounter – while (counter++ < 500000000){} ‒ SingleThreadSynchronizedCounter – 1T using synchronized ‒ TwoThreadsSynchronizedCounter – 2T using synchronized ‒ SingleThreadCASCounter – 1T using AtomicLong ‒ TwoThreadsCASCounter – 2T using AtomicLong ‒ TwoThreadsCASCounterLongAdder – 1T using LongAdder ‒ SingleThreadVolatileCounter – 1T, memory barrier (volatile) ‒ TwoThreadsVolatileCounter – 2T, memory barrier (volatile) Comparing Concurrent Impl.
  • 23.
    23 Test results (onmy laptop - quad core Intel [email protected]): − SynchronousCounter – 190ms − SingleThreadSynchronizedCounter – 15000 ms − TwoThreadsSynchronizedCounter – 21000 ms − SingleThreadCASCounter – 4100 ms − TwoThreadsCASCounter – 12000 ms − TwoThreadsCASCounterLongAdder – 12800 ms − SingleThreadVolatileCounter – 4100 ms − TwoThreadsVolatileCounter – 20000 ms Comparing Concurrent Impl.
  • 24.
    24 For more completemicro-benchmarking of different Mutex implementations see: http://blog.takipi.com/java-8-stampedlocks-vs- readwritelocks-and-synchronized/ http://www.slideshare.net/haimyadid/java-8- stamped-lock Comparing Concurrent Impl.
  • 25.
    25  Non-blocking (synchronous)implementation is 2 orders of magnitude better then synchronized  We should try to avoid blocking and especially contended blocking if want to achieve low latency  If blocking is a must we have to prefer CAS and optimistic concurrency over blocking (but have in mind it always depends on concurrent problem at hand and how much contention do we experience – test early, test often, microbenchmarks are unreliable and highly platform dependent – test real application with typical load patterns)  The real question is: HOW is is possible to build concurrency without blocking? Mutex Comparison => Conclusions
  • 26.
    26  Message Driven– asynchronous message-passing allows to establish a boundary between components that ensures loose coupling, isolation, location transparency, and provides the means to delegate errors as messages [Reactive Manifesto].  The main idea is to separate concurrent producer and consumer workers by using message queues.  Message queues can be unbounded or bounded (limited max number of messages)  Unbounded message queues can present memory allocation problem in case the producers outrun the consumers for a long period → OutOfMemoryError Scalable, Massively Concurrent
  • 27.
    27  Queues typicallyuse either linked-lists or arrays for the underlying storage of elements. Linked lists are not „mechanically sympathetic” – there is no predictable caching “stride” (should be less than 2048 bytes in each direction).  Bounded queues often experience write contention on head, tail, and size variables. Even if head and tail separated using CAS, they usually are in the same cache- line.  Queues produce much garbage.  Typical queues conflate a number of different concerns – producer and consumer synchronization and data storage Queues Disadvantages [http://lmax-exchange.github.com/disruptor/files/Disruptor-1.0.pdf]
  • 28.
    28  LMAX Disruptordesign pattern separates different concerns in a “mechanically sympathetic” way: - Storage of items being exchanged - Producer coordination – claiming the next sequence - Consumers coordination – notified new item is available  Single Writer principle is employed when writing data in the Ring Buffer from single producer thread only (no contention),  When multiple producers → CAS  Memory pre-allocated – predictable stride, no garbage LMAX Disruptor (RingBuffer) [http://lmax-exchange.github.com/disruptor/files/Disruptor-1.0.pdf]
  • 29.
    29 LMAX Disruptor (RingBuffer)High Performance [http://lmax-exchange.github.com/disruptor/files/Disruptor- 1.0.pdf] Source: LMAX Disruptor github wiki - https://raw.githubusercontent.com/wiki/LMAX- Exchange/disruptor/images/Models.png LMAX-Exchange Disruptor License @ GitHub: Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/
  • 30.
    30 LMAX Disruptor (RingBuffer)High Performance [http://lmax-exchange.github.com/disruptor/files/Disruptor- 1.0.pdf] Source: LMAX Disruptor @ GitHub - https://github.com/LMAX- Exchange/disruptor/blob/master/docs/Disruptor.docx LMAX-Exchange Disruptor License @ GitHub: Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/
  • 31.
    31 Project Reactor  Reactorproject allows building high-performance (low latency high throughput) non-blocking asynchronous applications on JVM.  Reactor is designed to be extraordinarily fast and can sustain throughput rates on order of 10's of millions of operations per second.  Reactor has powerful API for declaring data transformations and functional composition.  Makes use of the concept of Mechanical Sympathy built on top of Disruptor / RingBuffer.
  • 32.
    32 Project Reactor  Pre-allocationat startup-time  Message-passing structures are bounded  Using Reactive and Event-Driven Architecture patterns => non-blocking end-to-end flows, replies  Implement Reactive Streams Specification – efficient bounded structures requesting no more than capacity  Applies above features to IPC and provides non- blocking IO drivers that are flow-control aware  Expose a Functional API – organize their code in a side-effect free way, which helps you determine you are thread-safe and fault-tolerant
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
    37 Reactor: Hello World publicclass ReactorHelloWorld { public static void main(String... args) throws InterruptedException { Broadcaster<String> sink = Broadcaster.create(); SchedulerGroup sched = SchedulerGroup.async(); sink.dispatchOn(sched) .map(String::toUpperCase) .filter(s -> s.startsWith("HELLO")) .consume(s -> System.out.printf("s=%s%n", s)); sink.onNext("Hello World!"); sink.onNext("Goodbye World!"); Thread.sleep(500); } }
  • 38.
  • 39.
  • 40.
  • 41.
    41 IPTPI: RPi2 +Ardunio Robot  Raspberry Pi 2 (quad-core ARMv7 @ 900MHz) + Arduino Leonardo cloneA-Star 32U4 Micro  Optical encoders (custom), IR optical array, 3D accelerometers, gyros, and compass MinIMU-9 v2  IPTPI is programmed in Java using Pi4J, Reactor, RxJava, Akka  More information about IPTPI: http://robolearn.org/iptpi-robot/
  • 42.
    42 IPTPI: RPi2 +Ardunio Robot 3D accelerometers, gyros, and compass MinIMU-9 v2 Pololu DRV8835 Dual Motor Driver for Raspberry Pi Arduino Leonardo clone A-Star 32U4 Micro USB Stereo Speakers - 5V LiPo Powebank 15000 mAh
  • 43.
    43 IPTPI: RPi2 +Ardunio Robot Raspberry Pi 2 (quad-core ARMv7 @ 900MHz) IR Optical Sensor QRD1114 Array (Line Following) Adafruit 2.8" PiTFT - Capacitive Touch Screen
  • 44.
  • 45.
    45 LeJaRo: Lego® Java Robot Modular – 3 motors (with encoders) – one driving each track, and third for robot clamp.  Three sensors: touch sensor (obstacle avoidance), light color sensor (follow line), IR sensor (remote).  LeJaRo is programmed in Java using LeJOS library.  More information about LeJaRo: http://robolearn.org/lejaro/  Programming examples available @GitHub: https://github.com/iproduct/course-social-robotics/tre e/master/motors_demo LEGO® is a registered trademark of LEGO® Group. Programs of IPT are not affiliated, sponsored or endorsed by LEGO® Education or LEGO® Group.
  • 46.
  • 47.
    47 Let's See SomeReal Code  Reactive Websocket Demo available @GitHub: https://github.com/iproduct/ipt-angular2- reactive-websocket-demo Reactive Robotics Demo available @GitHub: https://github.com/iproduct/jprime-demo
  • 48.
  • 49.
    49 IPTPI: IPTPIDemo I publicclass IPTPIVDemo { ... public IPTPIDemo() { //receive Arduino data readings arduino = ArduinoDataFactory.createArduinoDataFluxion(); //calculate robot positions positionsPub =PositionFactory.createPositionFluxion(arduino); presentationViews.add( PositionFactory.createPositionPanel(positionsPub)); //wire robot main controller with services moveSub = MovementFactory .createCommandMovementSubscriber(positionsPub); controller = new RobotController( Subscribers.consumer(this::tearDown),moveSub);
  • 50.
    50 IPTPI: IPTPIDemo II //createview with controller and delegate material views //from query services view = new RobotView("IPTPI Reactive Robotics Demo", controller, presentationViews); //expose as WS service movementSub2 = MovementFactory .createCommandMovementSubscriber(positionsPub); positionsService = new RobotWSService(positionsPub, movementSub2); } public static void main(String[] args) { IPTPIVoxxedDemo demo = new IPTPIVoxxedDemo(); }
  • 51.
    51 IPTPI: ArduinoDataFluxion I fluxion= Broadcaster.create(); emitter = fluxion.startEmitter(); final Serial serial = SerialFactory.createInstance(); serial.addListener(new SerialDataEventListener() { private ByteBuffer buffer = ByteBuffer.allocate(1024); @Override public void dataReceived(SerialDataEvent event) { try { ByteBuffer newBuffer = event.getByteBuffer(); buffer.put(newBuffer); buffer.flip(); ... buffer.get(); long timestamp = buffer.getInt(); //get timestamp int encoderL = -buffer.getInt(); //motors mirrored int encoderR = buffer.getInt();
  • 52.
    52 IPTPI: ArduinoDataFluxion II EncoderReadingsreadings = new EncoderReadings(encoderR, encoderL, timestamp); emitter.submit(readings); ... buffer.compact(); } catch (Exception e) { e.printStackTrace(); } } }); try { serial.open(PORT, 38400); } catch(SerialPortException | IOException ex) { System.out.println(“SERIAL SETUP FAILED:"+ex.getMessage()); }
  • 53.
  • 54.
    54 CommandMovementSubscriber I public classCommandMovementSubscriber extends ConsumerSubscriber<Command<Movement>> { private PositionFluxion positions; public CommandMovementSubscriber(PositionFluxion positions){ this.positions = positions; Gpio.wiringPiSetupGpio(); // initialize wiringPi library Gpio.pinMode(5, Gpio.OUTPUT); // Motor direction pins Gpio.pinMode(6, Gpio.OUTPUT); Gpio.pinMode(12, Gpio.PWM_OUTPUT); // Motor speed pins Gpio.pinMode(13, Gpio.PWM_OUTPUT); Gpio.pwmSetMode(Gpio.PWM_MODE_MS); Gpio.pwmSetRange(MAX_SPEED); Gpio.pwmSetClock(CLOCK_DIVISOR); } @Override public void doNext(Command<Movement> command) { ... } }
  • 55.
    55 CommandMovementSubscriber II private voidrunMotors(MotorsCommand mc) { //setting motor directions Gpio.digitalWrite(5, mc.getDirR() > 0 ? 1 : 0); Gpio.digitalWrite(6, mc.getDirL() > 0 ? 1 : 0); //setting speed if(mc.getVelocityR()>=0 && mc.getVelocityR() <=MAX_SPEED) Gpio.pwmWrite(12, mc.getVelocityR()); // set speed if(mc.getVelocityL()>=0 && mc.getVelocityL() <=MAX_SPEED) Gpio.pwmWrite(13, mc.getVelocityL()); } }
  • 56.
    56 Reactor IO –NetStreams API http://projectreactor.io/io/docs/reference/, Apache License 2.0
  • 57.
    57 IPTPI: RobotWSService I privatevoid setupServer() throws InterruptedException { httpServer = NetStreams.<Buffer, Buffer>httpServer( HttpServerSpec<Buffer,Buffer> serverSpec -> serverSpec.listen("172.22.0.68", 80) ); httpServer.get("/", getStaticResourceHandler()); httpServer.get("/index.html", getStaticResourceHandler()); httpServer.get("/app/**", getStaticResourceHandler()); ... httpServer.ws("/ws", getWsHandler()); httpServer.start().subscribe( Subscribers.consumer(System.out::println)); }
  • 58.
    58 IPTPI: RobotWSService II privateReactorHttpHandler<Buffer, Buffer> getWsHandler() { return channel -> { System.out.println("Connected a websocket client: " + channel.remoteAddress()); channel.map(Buffer::asString).consume( json -> { System.out.printf(“WS Message: %s%n“, json); Movement movement = gson.fromJson(json, Movement.class); movementCommands.onNext(new Command<>("move", movement)); }); return positions.flatMap(position -> channel.writeWith( Flux.just(Buffer.wrap(gson.toJson(position))) )); }; }
  • 59.
    59 Takeaways: Why GoReactive? Benefits using Reactive Programming + DDD:  DDD helps to manage complexity in IoT and Robotics - many subsystems = sub-domains  Reactive Streams (Fluxes, Monos) = uni-directional data flows, CQRS, event sourcing, microservices  Reactive Streams can be non-blocking and highly efficient, or can utilize blocking if needed  Naturally implement state management patterns like Redux, allow time travel, replay and data analytics  Clear, declarative data transforms that scale (Map- Reduce, BigData, PaaS)
  • 60.
    60 Takeaways: Why MaybeNot? Cons using Reactive Programming + DDD:  DDD requires additional efforts to clearly separate different (sub) domains – DSL translators, factories...  Reactive Streams utilize functional composition and require entirely different mindset then imperative – feels like learning foreign language  Pure functions and Redux provide much benefits, but there's always temptation to “do it the old way” :)  Tool support for functional programming in Java is still not perfect (in Eclipse at least :)
  • 61.
    61 Resources: RxMarbles &Rx Coans RxMarbles: http://rxmarbles.com/ RxJava Koans – Let's try to solve them at: https://github.com/mutexkid/rxjava-koans RxJS Koans – for those who prefer JavaScript :) https://github.com/Reactive-Extensions/RxJSKoans
  • 62.
    62 Interested in Reactive? IPT Reactive Java and Angular 2 + Typescript courses: http://iproduct.org  More information about robots @RoboLearn: http://robolearn.org/  TuxCon – 9-10 July, Plovdiv: http://tuxcon.mobi/#schedule
  • 63.
    63 Tale of Simplicity:DDD 63 http://robolearn.org/
  • 64.
    64 Thank’s for YourAttention! Trayan Iliev CEO of IPT – Intellectual Products & Technologies http://iproduct.org/ http://robolearn.org/ https://github.com/iproduct https://twitter.com/trayaniliev https://www.facebook.com/IPT.EACAD https://plus.google.com/+IproductOrg